Struct atsamd_hal::pukcc::Pukcc
source · [−]pub struct Pukcc { /* private fields */ }
Expand description
Struct representing a PUKCC peripheral.
It provides an access to cryptographic algorithms in a safe, high-level manner
Implementations
sourceimpl Pukcc
impl Pukcc
sourcepub fn enable(mclk: &mut MCLK) -> Result<Self, SelfTestFailure>
pub fn enable(mclk: &mut MCLK) -> Result<Self, SelfTestFailure>
Constructor.
Waits for a CryptoRAM readiness, enables a synchronous PUKCC clock and performs a self test. In case a self test fails it returns an error
sourcepub fn self_test(&self) -> Result<(), SelfTestFailure>
pub fn self_test(&self) -> Result<(), SelfTestFailure>
Self test service.
Clears up a CryptoRAM and does the checksum. If a checksum and a version matches one defined in a HAL, it means that a self test passed successfully.
While using a high-level API, user should not need to use this service explicitly.
sourcepub fn zp_ecdsa_sign_with_entropy<C: Curve>(
&self,
signature: &mut [u8],
hash: &[u8],
private_key: &[u8],
k_buffer: &mut [u8],
k_entropy_source: &mut impl RngCore + CryptoRng
) -> Result<(), EcdsaSignFailure>
pub fn zp_ecdsa_sign_with_entropy<C: Curve>(
&self,
signature: &mut [u8],
hash: &[u8],
private_key: &[u8],
k_buffer: &mut [u8],
k_entropy_source: &mut impl RngCore + CryptoRng
) -> Result<(), EcdsaSignFailure>
Service generating an ECDSA signature.
GF(p) service. GF(2^n) variant is not implemented – use low-level API.
Input parameters:
hash
:&[u8]
of lengthCurve::SCALAR_LENGTH
- Hash of a message that is supposed to be signed.
private_key
:&[u8]
of lengthCurve::SCALAR_LENGTH
- Private key used for signing. Poorly generated
private_key
might have negative security implications.
- Private key used for signing. Poorly generated
k_buffer
:&mut [u8]
of lengthCurve::SCALAR_LENGTH
- Mutable buffer that is being populated by an entropy source and then used for signing.
k_entropy_source
:&mut (impl RngCore + CryptoRng)
- Generic source of cryptographically secure randomness.
Output parameters:
signature
:&mut [u8]
of length2 *
Curve::MOD_LENGTH
- Mutable slice that signature will be copied to from CryptoRAM
after generation is finished. First
Curve::MOD_LENGTH
bytes containR
part of a signature. LastCurve::MOD_LENGTH
bytes containS
part of a signature.
- Mutable slice that signature will be copied to from CryptoRAM
after generation is finished. First
Return value:
Result::Ok
- Signature was generated successfully
Result::Err
- Possible failure scenarios are encapsulated in a
EcdsaSignFailure
enum type
- Possible failure scenarios are encapsulated in a
Note: Provided Curve
needs to be sound. Otherwise, point
multiplication can become reversible (lack of trapdoor function
property) and an attacker might be able to reverse engineer a
private_key
from a signature
.
sourcepub unsafe fn zp_ecdsa_sign_with_raw_k<C: Curve>(
&self,
signature: &mut [u8],
hash: &[u8],
private_key: &[u8],
k: &[u8]
) -> Result<(), EcdsaSignFailure>
pub unsafe fn zp_ecdsa_sign_with_raw_k<C: Curve>(
&self,
signature: &mut [u8],
hash: &[u8],
private_key: &[u8],
k: &[u8]
) -> Result<(), EcdsaSignFailure>
Service generating an ECDSA signature.
GF(p) service. GF(2^n) variant is not implemented – use low-level API.
Input parameters:
hash
:&[u8]
of lengthCurve::SCALAR_LENGTH
- Hash of a message that is supposed to be signed.
private_key
:&[u8]
of lengthCurve::SCALAR_LENGTH
- Private key used for signing. Poorly generated
private_key
might have negative security implications.
- Private key used for signing. Poorly generated
k
:&[u8]
of lengthCurve::SCALAR_LENGTH
- A random number used for signature generation. It is heavily
encouraged to use cryptographically-secure random number
generators. One should never use the same
k
more than once. Private key can be extracted from signatures generated with a poorly randomized / the samek
value.
- A random number used for signature generation. It is heavily
encouraged to use cryptographically-secure random number
generators. One should never use the same
Exact same set of input parameters (hash, private_key and k) produces exactly the same signature.
Output parameters:
signature
:&mut [u8]
of length2 *
Curve::MOD_LENGTH
- Mutable slice that signature will be copied to from CryptoRAM
after generation is finished. First
Curve::MOD_LENGTH
bytes containR
part of a signature. LastCurve::MOD_LENGTH
bytes containS
part of a signature.
- Mutable slice that signature will be copied to from CryptoRAM
after generation is finished. First
Return value:
Result::Ok
- Signature was generated successfully
Result::Err
- Possible failure scenarios are encapsulated in a
EcdsaSignFailure
enum type
- Possible failure scenarios are encapsulated in a
Note: Provided Curve
needs to be sound. Otherwise, point
multiplication can become reversible (lack of trapdoor function
property) and an attacker might be able to reverse engineer a
private_key
from a signature
.
Safety
k
value must be cryptographically secure.
sourcepub fn zp_ecdsa_verify_signature<C: Curve>(
&self,
signature: &[u8],
hash: &[u8],
public_key: &[u8]
) -> Result<(), EcdsaSignatureVerificationFailure>
pub fn zp_ecdsa_verify_signature<C: Curve>(
&self,
signature: &[u8],
hash: &[u8],
public_key: &[u8]
) -> Result<(), EcdsaSignatureVerificationFailure>
Service verifying an ECDSA signature.
GF(p) service. GF(2^n) variant is not implemented – use low-level API.
Input parameters:
signature
:&[u8]
of length2 *
Curve::SCALAR_LENGTH
- Signature that is being verified
hash
:&[u8]
of lengthCurve::SCALAR_LENGTH
- Hash of a message that is signed.
public_key
:&[u8]
of lengthCurve::SCALAR_LENGTH
- Public key used for a signature verification.
Return value:
Result::Ok
- Signature is valid against chosen
hash
andpublic_key
- Signature is valid against chosen
Result::Err
- Possible failure scenarios are encapsulated in a
EcdsaSignatureVerificationFailure
enum type
- Possible failure scenarios are encapsulated in a
In case of an invalid signature the returned error type will be
EcdsaSignatureVerificationFailure::ServiceFailure
(
Warning
(
WrongSignature
))
sourcepub fn modular_exponentiation<'a>(
&self,
input: &[u8],
exponent: &[u8],
modulus: &[u8],
mode: ExpModMode,
window_size: ExpModWindowSize,
buffer: &'a mut [u8]
) -> Result<&'a [u8], ExpModFailure>
pub fn modular_exponentiation<'a>(
&self,
input: &[u8],
exponent: &[u8],
modulus: &[u8],
mode: ExpModMode,
window_size: ExpModWindowSize,
buffer: &'a mut [u8]
) -> Result<&'a [u8], ExpModFailure>
Service performing a modular exponentiation.
result = pow(input, exponent) % modulus
Input parameters:
input
:&[u8]
- Requirements:
len(input) <= len(modulus)
- Message, hash, any slice of data that will undergo modular exponentiation
- Requirements:
exponent
:&[u8]
- Requirements:
len(exponent) <= len(modulus)
- Requirements:
modulus
:&[u8]
- Requirements:
len(modulus) % 4
12 <= len(modulus) < ?
- Note: Maximum size depends on few factors like CryptoRAM and workspace window size. Consult the table with data layout down below.
- Requirements:
mode
:ExpModMode
- Mode of operation: use regular or fast variant of the underlying algorithm
- This parameter does not influence the end result of a computation
window_size
:ExpModWindowSize
- Enum describing 4 predefined workspace sizes (from smallest to biggest) in CryptoRAM.
- Bigger the workspace size - faster the algorithm can operate - greater limitations on input parameters are put (as they occupy CryptoRAM address space as well). Consult the table with data layout down below.
- This parameter does not influence the end result of a computation
buffer
:&'a mut [u8]
- Requirements:
len(buffer) >= len(modulus) + 5
- Buffer used internally for CNS calculation. Piece of it is used also for a return value.
- Requirements:
Return value:
Result::Ok(&'a [u8])
- Length:
len(modulus)
- A result of modular exponentiation
- Length:
Result::Err
- Possible failure scenarios are encapsulated in a
ExpModFailure
enum type
- Possible failure scenarios are encapsulated in a
Failing to meet the requirements for any input parameter will end up with an error being returned.
CryptoRAM is 4KiB
(0x1000
bytes) in size. Data layout in CryptoRAM
looks as follows and its size cannot go over the threshold of 4KiB
.
- modulus: len(modulus) + 4
- cns (reduction constant): len(modulus) + 8
- output/input (after/before calculation): len(modulus) + 16
- exponent: len(exponent) + 4 (+ padding to be % 4)
- workspace: (depending on `window_size`)
- ExpModWindowSize::One => 3 * (modulus.len() + 4) + 8
- ExpModWindowSize::Two => 4 * (modulus.len() + 4) + 8
- ExpModWindowSize::Three => 6 * (modulus.len() + 4) + 8
- ExpModWindowSize::Four => 10 * (modulus.len() + 4) + 8
RSA
This function can be used to perform RSA related computation like encryption, decryption, signature generation and validation.
- To encrypt
input
value, split public key into publicexponent
andmodulus
and pass them into the function. Return value is going to be a cipher of aninput
. - To decrypt
input
value, split private key into privateexponent
andmodulus
and pass them into the function. Return value is going to be a decryptedinput
. - To generate a signature, pass the hash of a message being signed
as an
input
into the function and use a private key. Return value is going to be a signature (encrypted hash). - To validate a signature, pass it as an
input
into the function and use the public key. Decrypted signature is an expected hash of a message. Calculate the hash of your message and compare it with an expected value. If they are the same, validation can be considered successful.
All RSA variants up to RSA4096 (included) will fit into CryptoRAM and therefore are supported.