mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-05-12 12:22:15 +00:00
Merge pull request #135 from ARMmbed/export_sanity_tests
Document asymmetric key export formats
This commit is contained in:
commit
c0454a7369
|
@ -360,17 +360,71 @@ typedef uint32_t psa_key_type_t;
|
||||||
*/
|
*/
|
||||||
#define PSA_KEY_TYPE_VENDOR_FLAG ((psa_key_type_t)0x80000000)
|
#define PSA_KEY_TYPE_VENDOR_FLAG ((psa_key_type_t)0x80000000)
|
||||||
|
|
||||||
#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t)0x7e000000)
|
#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t)0x70000000)
|
||||||
|
#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t)0x40000000)
|
||||||
|
#define PSA_KEY_TYPE_CATEGORY_RAW ((psa_key_type_t)0x50000000)
|
||||||
|
#define PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY ((psa_key_type_t)0x60000000)
|
||||||
|
#define PSA_KEY_TYPE_CATEGORY_KEY_PAIR ((psa_key_type_t)0x70000000)
|
||||||
|
|
||||||
|
#define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR ((psa_key_type_t)0x10000000)
|
||||||
|
|
||||||
|
/** Whether a key type is vendor-defined. */
|
||||||
|
#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \
|
||||||
|
(((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0)
|
||||||
|
|
||||||
|
/** Whether a key type is an unstructured array of bytes.
|
||||||
|
*
|
||||||
|
* This encompasses both symmetric keys and non-key data.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) \
|
||||||
|
(((type) & PSA_KEY_TYPE_CATEGORY_MASK & ~(psa_key_type_t)0x10000000) == \
|
||||||
|
PSA_KEY_TYPE_CATEGORY_SYMMETRIC)
|
||||||
|
|
||||||
|
/** Whether a key type is asymmetric: either a key pair or a public key. */
|
||||||
|
#define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \
|
||||||
|
(((type) & PSA_KEY_TYPE_CATEGORY_MASK \
|
||||||
|
& ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) == \
|
||||||
|
PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
|
||||||
|
/** Whether a key type is the public part of a key pair. */
|
||||||
|
#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) \
|
||||||
|
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
|
||||||
|
/** Whether a key type is a key pair containing a private part and a public
|
||||||
|
* part. */
|
||||||
|
#define PSA_KEY_TYPE_IS_KEYPAIR(type) \
|
||||||
|
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR)
|
||||||
|
/** The key pair type corresponding to a public key type.
|
||||||
|
*
|
||||||
|
* You may also pass a key pair type as \p type, it will be left unchanged.
|
||||||
|
*
|
||||||
|
* \param type A public key type or key pair type.
|
||||||
|
*
|
||||||
|
* \return The corresponding key pair type.
|
||||||
|
* If \p type is not a public key or a key pair,
|
||||||
|
* the return value is undefined.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type) \
|
||||||
|
((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
|
||||||
|
/** The public key type corresponding to a key pair type.
|
||||||
|
*
|
||||||
|
* You may also pass a key pair type as \p type, it will be left unchanged.
|
||||||
|
*
|
||||||
|
* \param type A public key type or key pair type.
|
||||||
|
*
|
||||||
|
* \return The corresponding public key type.
|
||||||
|
* If \p type is not a public key or a key pair,
|
||||||
|
* the return value is undefined.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \
|
||||||
|
((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
|
||||||
|
/** Whether a key type is an RSA key (pair or public-only). */
|
||||||
|
#define PSA_KEY_TYPE_IS_RSA(type) \
|
||||||
|
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||||
|
|
||||||
/** Raw data.
|
/** Raw data.
|
||||||
*
|
*
|
||||||
* A "key" of this type cannot be used for any cryptographic operation.
|
* A "key" of this type cannot be used for any cryptographic operation.
|
||||||
* Applications may use this type to store arbitrary data in the keystore. */
|
* Applications may use this type to store arbitrary data in the keystore. */
|
||||||
#define PSA_KEY_TYPE_RAW_DATA ((psa_key_type_t)0x02000000)
|
#define PSA_KEY_TYPE_RAW_DATA ((psa_key_type_t)0x50000001)
|
||||||
|
|
||||||
#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t)0x04000000)
|
|
||||||
#define PSA_KEY_TYPE_CATEGORY_ASYMMETRIC ((psa_key_type_t)0x06000000)
|
|
||||||
#define PSA_KEY_TYPE_PAIR_FLAG ((psa_key_type_t)0x01000000)
|
|
||||||
|
|
||||||
/** HMAC key.
|
/** HMAC key.
|
||||||
*
|
*
|
||||||
|
@ -380,21 +434,21 @@ typedef uint32_t psa_key_type_t;
|
||||||
* HMAC keys should generally have the same size as the underlying hash.
|
* HMAC keys should generally have the same size as the underlying hash.
|
||||||
* This size can be calculated with #PSA_HASH_SIZE(\c alg) where
|
* This size can be calculated with #PSA_HASH_SIZE(\c alg) where
|
||||||
* \c alg is the HMAC algorithm or the underlying hash algorithm. */
|
* \c alg is the HMAC algorithm or the underlying hash algorithm. */
|
||||||
#define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x02000001)
|
#define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x51000000)
|
||||||
|
|
||||||
/** A secret for key derivation.
|
/** A secret for key derivation.
|
||||||
*
|
*
|
||||||
* The key policy determines which key derivation algorithm the key
|
* The key policy determines which key derivation algorithm the key
|
||||||
* can be used for.
|
* can be used for.
|
||||||
*/
|
*/
|
||||||
#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x02000101)
|
#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x52000000)
|
||||||
|
|
||||||
/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
|
/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
|
||||||
*
|
*
|
||||||
* The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
|
* The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
|
||||||
* 32 bytes (AES-256).
|
* 32 bytes (AES-256).
|
||||||
*/
|
*/
|
||||||
#define PSA_KEY_TYPE_AES ((psa_key_type_t)0x04000001)
|
#define PSA_KEY_TYPE_AES ((psa_key_type_t)0x40000001)
|
||||||
|
|
||||||
/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES).
|
/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES).
|
||||||
*
|
*
|
||||||
|
@ -405,30 +459,30 @@ typedef uint32_t psa_key_type_t;
|
||||||
* deprecated and should only be used to decrypt legacy data. 3-key 3DES
|
* deprecated and should only be used to decrypt legacy data. 3-key 3DES
|
||||||
* is weak and deprecated and should only be used in legacy protocols.
|
* is weak and deprecated and should only be used in legacy protocols.
|
||||||
*/
|
*/
|
||||||
#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x04000002)
|
#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x40000002)
|
||||||
|
|
||||||
/** Key for an cipher, AEAD or MAC algorithm based on the
|
/** Key for an cipher, AEAD or MAC algorithm based on the
|
||||||
* Camellia block cipher. */
|
* Camellia block cipher. */
|
||||||
#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x04000003)
|
#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x40000003)
|
||||||
|
|
||||||
/** Key for the RC4 stream cipher.
|
/** Key for the RC4 stream cipher.
|
||||||
*
|
*
|
||||||
* Note that RC4 is weak and deprecated and should only be used in
|
* Note that RC4 is weak and deprecated and should only be used in
|
||||||
* legacy protocols. */
|
* legacy protocols. */
|
||||||
#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x04000004)
|
#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x40000004)
|
||||||
|
|
||||||
/** RSA public key. */
|
/** RSA public key. */
|
||||||
#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x06010000)
|
#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x60010000)
|
||||||
/** RSA key pair (private and public key). */
|
/** RSA key pair (private and public key). */
|
||||||
#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x07010000)
|
#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x70010000)
|
||||||
|
|
||||||
/** DSA public key. */
|
/** DSA public key. */
|
||||||
#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x06020000)
|
#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000)
|
||||||
/** DSA key pair (private and public key). */
|
/** DSA key pair (private and public key). */
|
||||||
#define PSA_KEY_TYPE_DSA_KEYPAIR ((psa_key_type_t)0x07020000)
|
#define PSA_KEY_TYPE_DSA_KEYPAIR ((psa_key_type_t)0x70020000)
|
||||||
|
|
||||||
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x06030000)
|
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000)
|
||||||
#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x07030000)
|
#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x70030000)
|
||||||
#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff)
|
#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff)
|
||||||
/** Elliptic curve key pair. */
|
/** Elliptic curve key pair. */
|
||||||
#define PSA_KEY_TYPE_ECC_KEYPAIR(curve) \
|
#define PSA_KEY_TYPE_ECC_KEYPAIR(curve) \
|
||||||
|
@ -437,32 +491,6 @@ typedef uint32_t psa_key_type_t;
|
||||||
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \
|
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \
|
||||||
(PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
|
(PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
|
||||||
|
|
||||||
/** Whether a key type is vendor-defined. */
|
|
||||||
#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \
|
|
||||||
(((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0)
|
|
||||||
|
|
||||||
/** Whether a key type is asymmetric: either a key pair or a public key. */
|
|
||||||
#define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \
|
|
||||||
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_ASYMMETRIC)
|
|
||||||
/** Whether a key type is the public part of a key pair. */
|
|
||||||
#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) \
|
|
||||||
(((type) & (PSA_KEY_TYPE_CATEGORY_MASK | PSA_KEY_TYPE_PAIR_FLAG)) == \
|
|
||||||
PSA_KEY_TYPE_CATEGORY_ASYMMETRIC)
|
|
||||||
/** Whether a key type is a key pair containing a private part and a public
|
|
||||||
* part. */
|
|
||||||
#define PSA_KEY_TYPE_IS_KEYPAIR(type) \
|
|
||||||
(((type) & (PSA_KEY_TYPE_CATEGORY_MASK | PSA_KEY_TYPE_PAIR_FLAG)) == \
|
|
||||||
(PSA_KEY_TYPE_CATEGORY_ASYMMETRIC | PSA_KEY_TYPE_PAIR_FLAG))
|
|
||||||
/** The key pair type corresponding to a public key type. */
|
|
||||||
#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type) \
|
|
||||||
((type) | PSA_KEY_TYPE_PAIR_FLAG)
|
|
||||||
/** The public key type corresponding to a key pair type. */
|
|
||||||
#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \
|
|
||||||
((type) & ~PSA_KEY_TYPE_PAIR_FLAG)
|
|
||||||
/** Whether a key type is an RSA key (pair or public-only). */
|
|
||||||
#define PSA_KEY_TYPE_IS_RSA(type) \
|
|
||||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
|
|
||||||
|
|
||||||
/** Whether a key type is an elliptic curve key (pair or public-only). */
|
/** Whether a key type is an elliptic curve key (pair or public-only). */
|
||||||
#define PSA_KEY_TYPE_IS_ECC(type) \
|
#define PSA_KEY_TYPE_IS_ECC(type) \
|
||||||
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \
|
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \
|
||||||
|
@ -1159,10 +1187,54 @@ psa_status_t psa_get_key_information(psa_key_slot_t key,
|
||||||
* - For Triple-DES, the format is the concatenation of the
|
* - For Triple-DES, the format is the concatenation of the
|
||||||
* two or three DES keys.
|
* two or three DES keys.
|
||||||
* - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEYPAIR), the format
|
* - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEYPAIR), the format
|
||||||
* is the non-encrypted DER representation defined by PKCS\#1 (RFC 8017)
|
* is the non-encrypted DER encoding of the representation defined by
|
||||||
* as RSAPrivateKey.
|
* PKCS\#1 (RFC 8017) as `RSAPrivateKey`, version 0.
|
||||||
* - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the format
|
* ```
|
||||||
* is the DER representation defined by RFC 5280 as SubjectPublicKeyInfo.
|
* RSAPrivateKey ::= SEQUENCE {
|
||||||
|
* version INTEGER, -- must be 0
|
||||||
|
* modulus INTEGER, -- n
|
||||||
|
* publicExponent INTEGER, -- e
|
||||||
|
* privateExponent INTEGER, -- d
|
||||||
|
* prime1 INTEGER, -- p
|
||||||
|
* prime2 INTEGER, -- q
|
||||||
|
* exponent1 INTEGER, -- d mod (p-1)
|
||||||
|
* exponent2 INTEGER, -- d mod (q-1)
|
||||||
|
* coefficient INTEGER, -- (inverse of q) mod p
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* - For DSA private keys (#PSA_KEY_TYPE_DSA_KEYPAIR), the format
|
||||||
|
* is the non-encrypted DER encoding of the representation used by
|
||||||
|
* OpenSSL and OpenSSH, whose structure is described in ASN.1 as follows:
|
||||||
|
* ```
|
||||||
|
* DSAPrivateKey ::= SEQUENCE {
|
||||||
|
* version INTEGER, -- must be 0
|
||||||
|
* prime INTEGER, -- p
|
||||||
|
* subprime INTEGER, -- q
|
||||||
|
* generator INTEGER, -- g
|
||||||
|
* public INTEGER, -- y
|
||||||
|
* private INTEGER, -- x
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* - For elliptic curve key pairs (key types for which
|
||||||
|
* #PSA_KEY_TYPE_IS_ECC_KEYPAIR is true), the format is the
|
||||||
|
* non-encrypted DER encoding of the representation defined by RFC 5915 as
|
||||||
|
* `ECPrivateKey`, version 1. The `ECParameters` field must be a
|
||||||
|
* `namedCurve` OID as specified in RFC 5480 §2.1.1.1. The public key
|
||||||
|
* must be present and must be an `ECPoint` in the same format
|
||||||
|
* (uncompressed variant) an ECC public key of the
|
||||||
|
* corresponding type exported with psa_export_public_key().
|
||||||
|
* ```
|
||||||
|
* ECPrivateKey ::= SEQUENCE {
|
||||||
|
* version INTEGER, -- must be 1
|
||||||
|
* privateKey OCTET STRING,
|
||||||
|
* -- `ceiling(log2(n)/8)`-byte string, big endian,
|
||||||
|
* -- where n is the order of the curve.
|
||||||
|
* parameters [0] IMPLICIT ECParameters {{ namedCurve }}, -- mandatory
|
||||||
|
* publicKey [1] IMPLICIT BIT STRING -- mandatory
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is
|
||||||
|
* true), the format is the same as for psa_export_public_key().
|
||||||
*
|
*
|
||||||
* \param key Slot whose content is to be exported. This must
|
* \param key Slot whose content is to be exported. This must
|
||||||
* be an occupied key slot.
|
* be an occupied key slot.
|
||||||
|
@ -1175,6 +1247,12 @@ psa_status_t psa_get_key_information(psa_key_slot_t key,
|
||||||
* \retval #PSA_ERROR_EMPTY_SLOT
|
* \retval #PSA_ERROR_EMPTY_SLOT
|
||||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||||
|
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||||
|
* The size of the \p data buffer is too small. You can determine a
|
||||||
|
* sufficient buffer size by calling
|
||||||
|
* #PSA_KEY_EXPORT_MAX_SIZE(\c type, \c bits)
|
||||||
|
* where \c type is the key type
|
||||||
|
* and \c bits is the key size in bits.
|
||||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||||
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||||
|
@ -1190,11 +1268,70 @@ psa_status_t psa_export_key(psa_key_slot_t key,
|
||||||
* The output of this function can be passed to psa_import_key() to
|
* The output of this function can be passed to psa_import_key() to
|
||||||
* create an object that is equivalent to the public key.
|
* create an object that is equivalent to the public key.
|
||||||
*
|
*
|
||||||
* For standard key types, the output format is as follows:
|
* The format is the DER representation defined by RFC 5280 as
|
||||||
|
* `SubjectPublicKeyInfo`, with the `subjectPublicKey` format
|
||||||
|
* specified below.
|
||||||
|
* ```
|
||||||
|
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||||
|
* algorithm AlgorithmIdentifier,
|
||||||
|
* subjectPublicKey BIT STRING }
|
||||||
|
* AlgorithmIdentifier ::= SEQUENCE {
|
||||||
|
* algorithm OBJECT IDENTIFIER,
|
||||||
|
* parameters ANY DEFINED BY algorithm OPTIONAL }
|
||||||
|
* ```
|
||||||
*
|
*
|
||||||
* - For RSA keys (#PSA_KEY_TYPE_RSA_KEYPAIR or #PSA_KEY_TYPE_RSA_PUBLIC_KEY),
|
* - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY),
|
||||||
* the format is the DER representation of the public key defined by RFC 5280
|
* the `subjectPublicKey` format is defined by RFC 3279 §2.3.1 as
|
||||||
* as SubjectPublicKeyInfo.
|
* `RSAPublicKey`,
|
||||||
|
* with the OID `rsaEncryption`,
|
||||||
|
* and with the parameters `NULL`.
|
||||||
|
* ```
|
||||||
|
* pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||||
|
* rsadsi(113549) pkcs(1) 1 }
|
||||||
|
* rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
|
||||||
|
*
|
||||||
|
* RSAPublicKey ::= SEQUENCE {
|
||||||
|
* modulus INTEGER, -- n
|
||||||
|
* publicExponent INTEGER } -- e
|
||||||
|
* ```
|
||||||
|
* - For DSA public keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY),
|
||||||
|
* the `subjectPublicKey` format is defined by RFC 3279 §2.3.2 as
|
||||||
|
* `DSAPublicKey`,
|
||||||
|
* with the OID `id-dsa`,
|
||||||
|
* and with the parameters `DSS-Parms`.
|
||||||
|
* ```
|
||||||
|
* id-dsa OBJECT IDENTIFIER ::= {
|
||||||
|
* iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 1 }
|
||||||
|
*
|
||||||
|
* Dss-Parms ::= SEQUENCE {
|
||||||
|
* p INTEGER,
|
||||||
|
* q INTEGER,
|
||||||
|
* g INTEGER }
|
||||||
|
* DSAPublicKey ::= INTEGER -- public key, Y
|
||||||
|
* ```
|
||||||
|
* - For elliptic curve public keys (key types for which
|
||||||
|
* #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true),
|
||||||
|
* the `subjectPublicKey` format is defined by RFC 3279 §2.3.5 as
|
||||||
|
* `ECPoint`, which contains the uncompressed
|
||||||
|
* representation defined by SEC1 §2.3.3.
|
||||||
|
* The OID is `id-ecPublicKey`,
|
||||||
|
* and the parameters must be given as a `namedCurve` OID as specified in
|
||||||
|
* RFC 5480 §2.1.1.1 or other applicable standards.
|
||||||
|
* ```
|
||||||
|
* ansi-X9-62 OBJECT IDENTIFIER ::=
|
||||||
|
* { iso(1) member-body(2) us(840) 10045 }
|
||||||
|
* id-public-key-type OBJECT IDENTIFIER ::= { ansi-X9.62 2 }
|
||||||
|
* id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
|
||||||
|
*
|
||||||
|
* ECPoint ::= ...
|
||||||
|
* -- first 8 bits: 0x04;
|
||||||
|
* -- then x_P as an n-bit string, big endian;
|
||||||
|
* -- then y_P as a n-bit string, big endian,
|
||||||
|
* -- where n is the order of the curve.
|
||||||
|
*
|
||||||
|
* EcpkParameters ::= CHOICE { -- other choices are not allowed
|
||||||
|
* namedCurve OBJECT IDENTIFIER }
|
||||||
|
* ```
|
||||||
*
|
*
|
||||||
* \param key Slot whose content is to be exported. This must
|
* \param key Slot whose content is to be exported. This must
|
||||||
* be an occupied key slot.
|
* be an occupied key slot.
|
||||||
|
@ -1206,6 +1343,14 @@ psa_status_t psa_export_key(psa_key_slot_t key,
|
||||||
* \retval #PSA_SUCCESS
|
* \retval #PSA_SUCCESS
|
||||||
* \retval #PSA_ERROR_EMPTY_SLOT
|
* \retval #PSA_ERROR_EMPTY_SLOT
|
||||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||||
|
* The key is neither a public key nor a key pair.
|
||||||
|
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||||
|
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||||
|
* The size of the \p data buffer is too small. You can determine a
|
||||||
|
* sufficient buffer size by calling
|
||||||
|
* #PSA_KEY_EXPORT_MAX_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(\c type), \c bits)
|
||||||
|
* where \c type is the key type
|
||||||
|
* and \c bits is the key size in bits.
|
||||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||||
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||||
|
|
|
@ -305,4 +305,212 @@
|
||||||
PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \
|
PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \
|
||||||
0)
|
0)
|
||||||
|
|
||||||
|
/* Maximum size of the ASN.1 encoding of an INTEGER with the specified
|
||||||
|
* number of bits.
|
||||||
|
*
|
||||||
|
* This definition assumes that bits <= 2^19 - 9 so that the length field
|
||||||
|
* is at most 3 bytes. The length of the encoding is the length of the
|
||||||
|
* bit string padded to a whole number of bytes plus:
|
||||||
|
* - 1 type byte;
|
||||||
|
* - 1 to 3 length bytes;
|
||||||
|
* - 0 to 1 bytes of leading 0 due to the sign bit.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(bits) \
|
||||||
|
((bits) / 8 + 5)
|
||||||
|
|
||||||
|
/* Maximum size of the export encoding of an RSA public key.
|
||||||
|
* Assumes that the public exponent is less than 2^32.
|
||||||
|
*
|
||||||
|
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||||
|
* algorithm AlgorithmIdentifier,
|
||||||
|
* subjectPublicKey BIT STRING } -- contains RSAPublicKey
|
||||||
|
* AlgorithmIdentifier ::= SEQUENCE {
|
||||||
|
* algorithm OBJECT IDENTIFIER,
|
||||||
|
* parameters NULL }
|
||||||
|
* RSAPublicKey ::= SEQUENCE {
|
||||||
|
* modulus INTEGER, -- n
|
||||||
|
* publicExponent INTEGER } -- e
|
||||||
|
*
|
||||||
|
* - 3 * 4 bytes of SEQUENCE overhead;
|
||||||
|
* - 1 + 1 + 9 bytes of algorithm (RSA OID);
|
||||||
|
* - 2 bytes of NULL;
|
||||||
|
* - 4 bytes of BIT STRING overhead;
|
||||||
|
* - n : INTEGER;
|
||||||
|
* - 7 bytes for the public exponent.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) \
|
||||||
|
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 36)
|
||||||
|
|
||||||
|
/* Maximum size of the export encoding of an RSA key pair.
|
||||||
|
* Assumes thatthe public exponent is less than 2^32 and that the size
|
||||||
|
* difference between the two primes is at most 1 bit.
|
||||||
|
*
|
||||||
|
* RSAPrivateKey ::= SEQUENCE {
|
||||||
|
* version Version, -- 0
|
||||||
|
* modulus INTEGER, -- N-bit
|
||||||
|
* publicExponent INTEGER, -- 32-bit
|
||||||
|
* privateExponent INTEGER, -- N-bit
|
||||||
|
* prime1 INTEGER, -- N/2-bit
|
||||||
|
* prime2 INTEGER, -- N/2-bit
|
||||||
|
* exponent1 INTEGER, -- N/2-bit
|
||||||
|
* exponent2 INTEGER, -- N/2-bit
|
||||||
|
* coefficient INTEGER, -- N/2-bit
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* - 4 bytes of SEQUENCE overhead;
|
||||||
|
* - 3 bytes of version;
|
||||||
|
* - 7 half-size INTEGERs plus 2 full-size INTEGERs,
|
||||||
|
* overapproximated as 9 half-size INTEGERS;
|
||||||
|
* - 7 bytes for the public exponent.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_EXPORT_RSA_KEYPAIR_MAX_SIZE(key_bits) \
|
||||||
|
(9 * PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE((key_bits) / 2 + 1) + 14)
|
||||||
|
|
||||||
|
/* Maximum size of the export encoding of a DSA public key.
|
||||||
|
*
|
||||||
|
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||||
|
* algorithm AlgorithmIdentifier,
|
||||||
|
* subjectPublicKey BIT STRING } -- contains DSAPublicKey
|
||||||
|
* AlgorithmIdentifier ::= SEQUENCE {
|
||||||
|
* algorithm OBJECT IDENTIFIER,
|
||||||
|
* parameters Dss-Parms } -- SEQUENCE of 3 INTEGERs
|
||||||
|
* DSAPublicKey ::= INTEGER -- public key, Y
|
||||||
|
*
|
||||||
|
* - 3 * 4 bytes of SEQUENCE overhead;
|
||||||
|
* - 1 + 1 + 7 bytes of algorithm (DSA OID);
|
||||||
|
* - 4 bytes of BIT STRING overhead;
|
||||||
|
* - 3 full-size INTEGERs (p, g, y);
|
||||||
|
* - 1 + 1 + 32 bytes for 1 sub-size INTEGER (q <= 256 bits).
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) \
|
||||||
|
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 59)
|
||||||
|
|
||||||
|
/* Maximum size of the export encoding of a DSA key pair.
|
||||||
|
*
|
||||||
|
* DSAPrivateKey ::= SEQUENCE {
|
||||||
|
* version Version, -- 0
|
||||||
|
* prime INTEGER, -- p
|
||||||
|
* subprime INTEGER, -- q
|
||||||
|
* generator INTEGER, -- g
|
||||||
|
* public INTEGER, -- y
|
||||||
|
* private INTEGER, -- x
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* - 4 bytes of SEQUENCE overhead;
|
||||||
|
* - 3 bytes of version;
|
||||||
|
* - 3 full-size INTEGERs (p, g, y);
|
||||||
|
* - 2 * (1 + 1 + 32) bytes for 2 sub-size INTEGERs (q, x <= 256 bits).
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_EXPORT_DSA_KEYPAIR_MAX_SIZE(key_bits) \
|
||||||
|
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 75)
|
||||||
|
|
||||||
|
/* Maximum size of the export encoding of an ECC public key.
|
||||||
|
*
|
||||||
|
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||||
|
* algorithm AlgorithmIdentifier,
|
||||||
|
* subjectPublicKey BIT STRING } -- contains ECPoint
|
||||||
|
* AlgorithmIdentifier ::= SEQUENCE {
|
||||||
|
* algorithm OBJECT IDENTIFIER,
|
||||||
|
* parameters OBJECT IDENTIFIER } -- namedCurve
|
||||||
|
* ECPoint ::= ...
|
||||||
|
* -- first 8 bits: 0x04;
|
||||||
|
* -- then x_P as an n-bit string, big endian;
|
||||||
|
* -- then y_P as a n-bit string, big endian,
|
||||||
|
* -- where n is the order of the curve.
|
||||||
|
*
|
||||||
|
* - 2 * 4 bytes of SEQUENCE overhead;
|
||||||
|
* - 1 + 1 + 7 bytes of algorithm (id-ecPublicKey OID);
|
||||||
|
* - 1 + 1 + 12 bytes of namedCurve OID;
|
||||||
|
* - 4 bytes of BIT STRING overhead;
|
||||||
|
* - 1 byte + 2 * point size in ECPoint.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \
|
||||||
|
(2 * PSA_BITS_TO_BYTES(key_bits) + 36)
|
||||||
|
|
||||||
|
/* Maximum size of the export encoding of an ECC key pair.
|
||||||
|
*
|
||||||
|
* ECPrivateKey ::= SEQUENCE {
|
||||||
|
* version INTEGER, -- must be 1
|
||||||
|
* privateKey OCTET STRING,
|
||||||
|
* -- `ceiling(log2(n)/8)`-byte string, big endian,
|
||||||
|
* -- where n is the order of the curve.
|
||||||
|
* parameters [0] IMPLICIT ECParameters {{ NamedCurve }},
|
||||||
|
* publicKey [1] IMPLICIT BIT STRING
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* - 4 bytes of SEQUENCE overhead;
|
||||||
|
* - 1 * point size in privateKey
|
||||||
|
* - 1 + 1 + 12 bytes of namedCurve OID;
|
||||||
|
* - 4 bytes of BIT STRING overhead;
|
||||||
|
* - public key as for #PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_EXPORT_ECC_KEYPAIR_MAX_SIZE(key_bits) \
|
||||||
|
(3 * PSA_BITS_TO_BYTES(key_bits) + 56)
|
||||||
|
|
||||||
|
/** Safe output buffer size for psa_export_key() or psa_export_public_key().
|
||||||
|
*
|
||||||
|
* This macro returns a compile-time constant if its arguments are
|
||||||
|
* compile-time constants.
|
||||||
|
*
|
||||||
|
* \warning This function may call its arguments multiple times or
|
||||||
|
* zero times, so you should not pass arguments that contain
|
||||||
|
* side effects.
|
||||||
|
*
|
||||||
|
* The following code illustrates how to allocate enough memory to export
|
||||||
|
* a key by querying the key type and size at runtime.
|
||||||
|
* \code{c}
|
||||||
|
* psa_key_type_t key_type;
|
||||||
|
* size_t key_bits;
|
||||||
|
* psa_status_t status;
|
||||||
|
* status = psa_get_key_information(key, &key_type, &key_bits);
|
||||||
|
* if (status != PSA_SUCCESS) handle_error(...);
|
||||||
|
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits);
|
||||||
|
* unsigned char *buffer = malloc(buffer_size);
|
||||||
|
* if (buffer != NULL) handle_error(...);
|
||||||
|
* size_t buffer_length;
|
||||||
|
* status = psa_export_key(key, buffer, buffer_size, &buffer_length);
|
||||||
|
* if (status != PSA_SUCCESS) handle_error(...);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* For psa_export_public_key(), calculate the buffer size from the
|
||||||
|
* public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR
|
||||||
|
* to convert a key pair type to the corresponding public key type.
|
||||||
|
* \code{c}
|
||||||
|
* psa_key_type_t key_type;
|
||||||
|
* size_t key_bits;
|
||||||
|
* psa_status_t status;
|
||||||
|
* status = psa_get_key_information(key, &key_type, &key_bits);
|
||||||
|
* if (status != PSA_SUCCESS) handle_error(...);
|
||||||
|
* psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(key_type);
|
||||||
|
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(public_key_type, key_bits);
|
||||||
|
* unsigned char *buffer = malloc(buffer_size);
|
||||||
|
* if (buffer != NULL) handle_error(...);
|
||||||
|
* size_t buffer_length;
|
||||||
|
* status = psa_export_public_key(key, buffer, buffer_size, &buffer_length);
|
||||||
|
* if (status != PSA_SUCCESS) handle_error(...);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \param key_type A supported key type.
|
||||||
|
* \param key_bits The size of the key in bits.
|
||||||
|
*
|
||||||
|
* \return If the parameters are valid and supported, return
|
||||||
|
* a buffer size in bytes that guarantees that
|
||||||
|
* psa_asymmetric_sign() will not fail with
|
||||||
|
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||||
|
* If the parameters are a valid combination that is not supported
|
||||||
|
* by the implementation, this macro either shall return either a
|
||||||
|
* sensible size or 0.
|
||||||
|
* If the parameters are not valid, the
|
||||||
|
* return value is unspecified.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) \
|
||||||
|
(PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
|
||||||
|
(key_type) == PSA_KEY_TYPE_RSA_KEYPAIR ? PSA_KEY_EXPORT_RSA_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||||
|
(key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||||
|
(key_type) == PSA_KEY_TYPE_DSA_KEYPAIR ? PSA_KEY_EXPORT_DSA_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||||
|
(key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||||
|
PSA_KEY_TYPE_IS_ECC_KEYPAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||||
|
PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||||
|
0)
|
||||||
|
|
||||||
#endif /* PSA_CRYPTO_SIZES_H */
|
#endif /* PSA_CRYPTO_SIZES_H */
|
||||||
|
|
|
@ -135,9 +135,7 @@ typedef struct
|
||||||
|
|
||||||
static int key_type_is_raw_bytes( psa_key_type_t type )
|
static int key_type_is_raw_bytes( psa_key_type_t type )
|
||||||
{
|
{
|
||||||
psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
|
return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
|
||||||
return( category == PSA_KEY_TYPE_RAW_DATA ||
|
|
||||||
category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
#include "spm/psa_defs.h"
|
#include "spm/psa_defs.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "mbedtls/asn1.h"
|
||||||
#include "mbedtls/asn1write.h"
|
#include "mbedtls/asn1write.h"
|
||||||
|
#include "mbedtls/oid.h"
|
||||||
|
|
||||||
#include "psa/crypto.h"
|
#include "psa/crypto.h"
|
||||||
|
|
||||||
#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
|
#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
|
||||||
|
@ -38,13 +41,6 @@ static int mem_is_zero( void *buffer, size_t size )
|
||||||
return( 1 );
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int key_type_is_raw_bytes( psa_key_type_t type )
|
|
||||||
{
|
|
||||||
psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
|
|
||||||
return( category == PSA_KEY_TYPE_RAW_DATA ||
|
|
||||||
category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
|
/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
|
||||||
static int asn1_write_10x( unsigned char **p,
|
static int asn1_write_10x( unsigned char **p,
|
||||||
unsigned char *start,
|
unsigned char *start,
|
||||||
|
@ -393,6 +389,366 @@ exit:
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_oid_of_key_type( psa_key_type_t type,
|
||||||
|
const uint8_t *oid, size_t oid_length )
|
||||||
|
{
|
||||||
|
const uint8_t *expected_oid = NULL;
|
||||||
|
size_t expected_oid_length = 0;
|
||||||
|
#if defined(MBEDTLS_RSA_C)
|
||||||
|
if( PSA_KEY_TYPE_IS_RSA( type ) )
|
||||||
|
{
|
||||||
|
expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
|
||||||
|
expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* MBEDTLS_RSA_C */
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
|
if( PSA_KEY_TYPE_IS_ECC( type ) )
|
||||||
|
{
|
||||||
|
expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
|
||||||
|
expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
{
|
||||||
|
char message[40];
|
||||||
|
mbedtls_snprintf( message, sizeof( message ),
|
||||||
|
"OID not known for key type=0x%08lx",
|
||||||
|
(unsigned long) type );
|
||||||
|
test_fail( message, __LINE__, __FILE__ );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_ASSERT( oid_length == expected_oid_length );
|
||||||
|
TEST_ASSERT( memcmp( oid, expected_oid, oid_length ) == 0 );
|
||||||
|
return( 1 );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
|
||||||
|
size_t min_bits, size_t max_bits,
|
||||||
|
int must_be_odd )
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
size_t actual_bits;
|
||||||
|
unsigned char msb;
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_tag( p, end, &len,
|
||||||
|
MBEDTLS_ASN1_INTEGER ) == 0 );
|
||||||
|
/* Tolerate a slight departure from DER encoding:
|
||||||
|
* - 0 may be represented by an empty string or a 1-byte string.
|
||||||
|
* - The sign bit may be used as a value bit. */
|
||||||
|
if( ( len == 1 && ( *p )[0] == 0 ) ||
|
||||||
|
( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
|
||||||
|
{
|
||||||
|
++( *p );
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
if( min_bits == 0 && len == 0 )
|
||||||
|
return( 1 );
|
||||||
|
msb = ( *p )[0];
|
||||||
|
TEST_ASSERT( msb != 0 );
|
||||||
|
actual_bits = 8 * ( len - 1 );
|
||||||
|
while( msb != 0 )
|
||||||
|
{
|
||||||
|
msb >>= 1;
|
||||||
|
++actual_bits;
|
||||||
|
}
|
||||||
|
TEST_ASSERT( actual_bits >= min_bits );
|
||||||
|
TEST_ASSERT( actual_bits <= max_bits );
|
||||||
|
if( must_be_odd )
|
||||||
|
TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
|
||||||
|
*p += len;
|
||||||
|
return( 1 );
|
||||||
|
exit:
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
|
||||||
|
size_t *len,
|
||||||
|
unsigned char n, unsigned char tag )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = mbedtls_asn1_get_tag( p, end, len,
|
||||||
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||||
|
MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
end = *p + *len;
|
||||||
|
ret = mbedtls_asn1_get_tag( p, end, len, tag );
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
if( *p + *len != end )
|
||||||
|
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
|
||||||
|
uint8_t *exported, size_t exported_length )
|
||||||
|
{
|
||||||
|
if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
|
||||||
|
TEST_ASSERT( exported_length == ( bits + 7 ) / 8 );
|
||||||
|
else
|
||||||
|
TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_DES_C)
|
||||||
|
if( type == PSA_KEY_TYPE_DES )
|
||||||
|
{
|
||||||
|
/* Check the parity bits. */
|
||||||
|
unsigned i;
|
||||||
|
for( i = 0; i < bits / 8; i++ )
|
||||||
|
{
|
||||||
|
unsigned bit_count = 0;
|
||||||
|
unsigned m;
|
||||||
|
for( m = 1; m <= 0x100; m <<= 1 )
|
||||||
|
{
|
||||||
|
if( exported[i] & m )
|
||||||
|
++bit_count;
|
||||||
|
}
|
||||||
|
TEST_ASSERT( bit_count % 2 != 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
|
||||||
|
if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
|
||||||
|
{
|
||||||
|
uint8_t *p = exported;
|
||||||
|
uint8_t *end = exported + exported_length;
|
||||||
|
size_t len;
|
||||||
|
/* RSAPrivateKey ::= SEQUENCE {
|
||||||
|
* version INTEGER, -- must be 0
|
||||||
|
* modulus INTEGER, -- n
|
||||||
|
* publicExponent INTEGER, -- e
|
||||||
|
* privateExponent INTEGER, -- d
|
||||||
|
* prime1 INTEGER, -- p
|
||||||
|
* prime2 INTEGER, -- q
|
||||||
|
* exponent1 INTEGER, -- d mod (p-1)
|
||||||
|
* exponent2 INTEGER, -- d mod (q-1)
|
||||||
|
* coefficient INTEGER, -- (inverse of q) mod p
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_SEQUENCE |
|
||||||
|
MBEDTLS_ASN1_CONSTRUCTED ) == 0 );
|
||||||
|
TEST_ASSERT( p + len == end );
|
||||||
|
if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
|
||||||
|
goto exit;
|
||||||
|
if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
|
||||||
|
goto exit;
|
||||||
|
if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
|
||||||
|
goto exit;
|
||||||
|
/* Require d to be at least half the size of n. */
|
||||||
|
if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
|
||||||
|
goto exit;
|
||||||
|
/* Require p and q to be at most half the size of n, rounded up. */
|
||||||
|
if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
|
||||||
|
goto exit;
|
||||||
|
if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
|
||||||
|
goto exit;
|
||||||
|
if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
|
||||||
|
goto exit;
|
||||||
|
if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
|
||||||
|
goto exit;
|
||||||
|
if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
|
||||||
|
goto exit;
|
||||||
|
TEST_ASSERT( p == end );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* MBEDTLS_RSA_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
|
if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
|
||||||
|
{
|
||||||
|
uint8_t *p = exported;
|
||||||
|
uint8_t *end = exported + exported_length;
|
||||||
|
size_t len;
|
||||||
|
int version;
|
||||||
|
/* ECPrivateKey ::= SEQUENCE {
|
||||||
|
* version INTEGER, -- must be 1
|
||||||
|
* privateKey OCTET STRING,
|
||||||
|
* -- `ceiling(log_{256}(n))`-byte string, big endian,
|
||||||
|
* -- where n is the order of the curve.
|
||||||
|
* parameters ECParameters {{ NamedCurve }}, -- mandatory
|
||||||
|
* publicKey BIT STRING -- mandatory
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_SEQUENCE |
|
||||||
|
MBEDTLS_ASN1_CONSTRUCTED ) == 0 );
|
||||||
|
TEST_ASSERT( p + len == end );
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_int( &p, end, &version ) == 0 );
|
||||||
|
TEST_ASSERT( version == 1 );
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_OCTET_STRING ) == 0 );
|
||||||
|
/* Bug in Mbed TLS: the length of the octet string depends on the value */
|
||||||
|
// TEST_ASSERT( len == PSA_BITS_TO_BYTES( bits ) );
|
||||||
|
p += len;
|
||||||
|
TEST_ASSERT( asn1_get_implicit_tag( &p, end, &len, 0,
|
||||||
|
MBEDTLS_ASN1_OID ) == 0 );
|
||||||
|
p += len;
|
||||||
|
/* publicKey: ECPoint in uncompressed representation (as below) */
|
||||||
|
TEST_ASSERT( asn1_get_implicit_tag( &p, end, &len, 1,
|
||||||
|
MBEDTLS_ASN1_BIT_STRING ) == 0 );
|
||||||
|
TEST_ASSERT( p + len == end );
|
||||||
|
TEST_ASSERT( p[0] == 0 ); /* 0 unused bits in the bit string */
|
||||||
|
++p;
|
||||||
|
TEST_ASSERT( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ) == end );
|
||||||
|
TEST_ASSERT( p[0] == 4 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
|
||||||
|
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
|
||||||
|
{
|
||||||
|
uint8_t *p = exported;
|
||||||
|
uint8_t *end = exported + exported_length;
|
||||||
|
size_t len;
|
||||||
|
mbedtls_asn1_buf alg;
|
||||||
|
mbedtls_asn1_buf params;
|
||||||
|
mbedtls_asn1_bitstring bitstring;
|
||||||
|
/* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||||
|
* algorithm AlgorithmIdentifier,
|
||||||
|
* subjectPublicKey BIT STRING }
|
||||||
|
* AlgorithmIdentifier ::= SEQUENCE {
|
||||||
|
* algorithm OBJECT IDENTIFIER,
|
||||||
|
* parameters ANY DEFINED BY algorithm OPTIONAL }
|
||||||
|
*/
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_SEQUENCE |
|
||||||
|
MBEDTLS_ASN1_CONSTRUCTED ) == 0 );
|
||||||
|
TEST_ASSERT( p + len == end );
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_alg( &p, end, &alg, ¶ms ) == 0 );
|
||||||
|
if( ! is_oid_of_key_type( type, alg.p, alg.len ) )
|
||||||
|
goto exit;
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_bitstring( &p, end, &bitstring ) == 0 );
|
||||||
|
TEST_ASSERT( p == end );
|
||||||
|
p = bitstring.p;
|
||||||
|
#if defined(MBEDTLS_RSA_C)
|
||||||
|
if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
|
||||||
|
{
|
||||||
|
/* RSAPublicKey ::= SEQUENCE {
|
||||||
|
* modulus INTEGER, -- n
|
||||||
|
* publicExponent INTEGER } -- e
|
||||||
|
*/
|
||||||
|
TEST_ASSERT( bitstring.unused_bits == 0 );
|
||||||
|
TEST_ASSERT( mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_SEQUENCE |
|
||||||
|
MBEDTLS_ASN1_CONSTRUCTED ) == 0 );
|
||||||
|
TEST_ASSERT( p + len == end );
|
||||||
|
if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
|
||||||
|
goto exit;
|
||||||
|
if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
|
||||||
|
goto exit;
|
||||||
|
TEST_ASSERT( p == end );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* MBEDTLS_RSA_C */
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
|
if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
|
||||||
|
{
|
||||||
|
/* ECPoint ::= ...
|
||||||
|
* -- first 8 bits: 0x04 (uncompressed representation);
|
||||||
|
* -- then x_P as an n-bit string, big endian;
|
||||||
|
* -- then y_P as a n-bit string, big endian,
|
||||||
|
* -- where n is the order of the curve.
|
||||||
|
*/
|
||||||
|
TEST_ASSERT( bitstring.unused_bits == 0 );
|
||||||
|
TEST_ASSERT( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ) == end );
|
||||||
|
TEST_ASSERT( p[0] == 4 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
{
|
||||||
|
char message[40];
|
||||||
|
mbedtls_snprintf( message, sizeof( message ),
|
||||||
|
"No sanity check for public key type=0x%08lx",
|
||||||
|
(unsigned long) type );
|
||||||
|
test_fail( message, __LINE__, __FILE__ );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
{
|
||||||
|
/* No sanity checks for other types */
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exercise_export_key( psa_key_slot_t slot,
|
||||||
|
psa_key_usage_t usage )
|
||||||
|
{
|
||||||
|
psa_key_type_t type;
|
||||||
|
size_t bits;
|
||||||
|
uint8_t *exported = NULL;
|
||||||
|
size_t exported_size = 0;
|
||||||
|
size_t exported_length = 0;
|
||||||
|
int ok = 0;
|
||||||
|
|
||||||
|
if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 )
|
||||||
|
{
|
||||||
|
TEST_ASSERT( psa_export_key( slot, NULL, 0, &exported_length ) ==
|
||||||
|
PSA_ERROR_NOT_PERMITTED );
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_ASSERT( psa_get_key_information( slot, &type, &bits ) == PSA_SUCCESS );
|
||||||
|
exported_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
|
||||||
|
exported = mbedtls_calloc( 1, exported_size );
|
||||||
|
TEST_ASSERT( exported != NULL );
|
||||||
|
|
||||||
|
TEST_ASSERT( psa_export_key( slot,
|
||||||
|
exported, exported_size,
|
||||||
|
&exported_length ) == PSA_SUCCESS );
|
||||||
|
ok = exported_key_sanity_check( type, bits, exported, exported_length );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_free( exported );
|
||||||
|
return( ok );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exercise_export_public_key( psa_key_slot_t slot )
|
||||||
|
{
|
||||||
|
psa_key_type_t type;
|
||||||
|
psa_key_type_t public_type;
|
||||||
|
size_t bits;
|
||||||
|
uint8_t *exported = NULL;
|
||||||
|
size_t exported_size = 0;
|
||||||
|
size_t exported_length = 0;
|
||||||
|
int ok = 0;
|
||||||
|
|
||||||
|
TEST_ASSERT( psa_get_key_information( slot, &type, &bits ) == PSA_SUCCESS );
|
||||||
|
if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( type ) )
|
||||||
|
{
|
||||||
|
TEST_ASSERT( psa_export_public_key( slot,
|
||||||
|
NULL, 0, &exported_length ) ==
|
||||||
|
PSA_ERROR_INVALID_ARGUMENT );
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
|
||||||
|
exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type, bits );
|
||||||
|
exported = mbedtls_calloc( 1, exported_size );
|
||||||
|
TEST_ASSERT( exported != NULL );
|
||||||
|
|
||||||
|
TEST_ASSERT( psa_export_public_key( slot,
|
||||||
|
exported, exported_size,
|
||||||
|
&exported_length ) == PSA_SUCCESS );
|
||||||
|
ok = exported_key_sanity_check( public_type, bits,
|
||||||
|
exported, exported_length );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_free( exported );
|
||||||
|
return( ok );
|
||||||
|
}
|
||||||
|
|
||||||
static int exercise_key( psa_key_slot_t slot,
|
static int exercise_key( psa_key_slot_t slot,
|
||||||
psa_key_usage_t usage,
|
psa_key_usage_t usage,
|
||||||
psa_algorithm_t alg )
|
psa_algorithm_t alg )
|
||||||
|
@ -421,6 +777,10 @@ static int exercise_key( psa_key_slot_t slot,
|
||||||
test_fail( message, __LINE__, __FILE__ );
|
test_fail( message, __LINE__, __FILE__ );
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ok = ok && exercise_export_key( slot, usage );
|
||||||
|
ok = ok && exercise_export_public_key( slot );
|
||||||
|
|
||||||
return( ok );
|
return( ok );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,6 +992,9 @@ void import_export( data_t *data,
|
||||||
goto destroy;
|
goto destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ! exercise_export_key( slot, usage_arg ) )
|
||||||
|
goto exit;
|
||||||
|
|
||||||
if( canonical_input )
|
if( canonical_input )
|
||||||
{
|
{
|
||||||
TEST_ASSERT( exported_length == data->len );
|
TEST_ASSERT( exported_length == data->len );
|
||||||
|
@ -1128,7 +1491,7 @@ exit:
|
||||||
void key_lifetime( int lifetime_arg )
|
void key_lifetime( int lifetime_arg )
|
||||||
{
|
{
|
||||||
int key_slot = 1;
|
int key_slot = 1;
|
||||||
psa_key_type_t key_type = PSA_ALG_CBC_BASE;
|
psa_key_type_t key_type = PSA_KEY_TYPE_RAW_DATA;
|
||||||
unsigned char key[32] = {0};
|
unsigned char key[32] = {0};
|
||||||
psa_key_lifetime_t lifetime_set = lifetime_arg;
|
psa_key_lifetime_t lifetime_set = lifetime_arg;
|
||||||
psa_key_lifetime_t lifetime_get;
|
psa_key_lifetime_t lifetime_get;
|
||||||
|
@ -3056,10 +3419,6 @@ void generate_key( int type_arg,
|
||||||
psa_status_t expected_status = expected_status_arg;
|
psa_status_t expected_status = expected_status_arg;
|
||||||
psa_key_type_t got_type;
|
psa_key_type_t got_type;
|
||||||
size_t got_bits;
|
size_t got_bits;
|
||||||
unsigned char exported[616] = {0}; /* enough for a 1024-bit RSA key */
|
|
||||||
size_t exported_length;
|
|
||||||
psa_status_t expected_export_status =
|
|
||||||
usage & PSA_KEY_USAGE_EXPORT ? PSA_SUCCESS : PSA_ERROR_NOT_PERMITTED;
|
|
||||||
psa_status_t expected_info_status =
|
psa_status_t expected_info_status =
|
||||||
expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_EMPTY_SLOT;
|
expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_EMPTY_SLOT;
|
||||||
psa_key_policy_t policy;
|
psa_key_policy_t policy;
|
||||||
|
@ -3083,84 +3442,6 @@ void generate_key( int type_arg,
|
||||||
TEST_ASSERT( got_type == type );
|
TEST_ASSERT( got_type == type );
|
||||||
TEST_ASSERT( got_bits == bits );
|
TEST_ASSERT( got_bits == bits );
|
||||||
|
|
||||||
/* Export the key */
|
|
||||||
TEST_ASSERT( psa_export_key( slot,
|
|
||||||
exported, sizeof( exported ),
|
|
||||||
&exported_length ) == expected_export_status );
|
|
||||||
if( expected_export_status == PSA_SUCCESS )
|
|
||||||
{
|
|
||||||
if( key_type_is_raw_bytes( type ) )
|
|
||||||
TEST_ASSERT( exported_length == ( bits + 7 ) / 8 );
|
|
||||||
#if defined(MBEDTLS_DES_C)
|
|
||||||
if( type == PSA_KEY_TYPE_DES )
|
|
||||||
{
|
|
||||||
/* Check the parity bits. */
|
|
||||||
unsigned i;
|
|
||||||
for( i = 0; i < bits / 8; i++ )
|
|
||||||
{
|
|
||||||
unsigned bit_count = 0;
|
|
||||||
unsigned m;
|
|
||||||
for( m = 1; m <= 0x100; m <<= 1 )
|
|
||||||
{
|
|
||||||
if( exported[i] & m )
|
|
||||||
++bit_count;
|
|
||||||
}
|
|
||||||
TEST_ASSERT( bit_count % 2 != 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
|
|
||||||
if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
|
|
||||||
{
|
|
||||||
/* Sanity check: does this look like the beginning of a PKCS#8
|
|
||||||
* RSA key pair? Assumes bits is a multiple of 8. */
|
|
||||||
size_t n_bytes = bits / 8 + 1;
|
|
||||||
size_t n_encoded_bytes;
|
|
||||||
unsigned char *n_end;
|
|
||||||
TEST_ASSERT( exported_length >= 7 + ( n_bytes + 3 ) * 9 / 2 );
|
|
||||||
TEST_ASSERT( exported[0] == 0x30 );
|
|
||||||
TEST_ASSERT( exported[1] == 0x82 ); // assumes >=416-bit key
|
|
||||||
TEST_ASSERT( exported[4] == 0x02 );
|
|
||||||
TEST_ASSERT( exported[5] == 0x01 );
|
|
||||||
TEST_ASSERT( exported[6] == 0x00 );
|
|
||||||
TEST_ASSERT( exported[7] == 0x02 );
|
|
||||||
n_encoded_bytes = exported[8];
|
|
||||||
n_end = exported + 9 + n_encoded_bytes;
|
|
||||||
if( n_encoded_bytes & 0x80 )
|
|
||||||
{
|
|
||||||
n_encoded_bytes = ( n_encoded_bytes & 0x7f ) << 7;
|
|
||||||
n_encoded_bytes |= exported[9] & 0x7f;
|
|
||||||
n_end += 1;
|
|
||||||
}
|
|
||||||
/* The encoding of n should start with a 0 byte since it should
|
|
||||||
* have its high bit set. However Mbed TLS is not compliant and
|
|
||||||
* generates an invalid, but widely tolerated, encoding of
|
|
||||||
* positive INTEGERs with a bit size that is a multiple of 8
|
|
||||||
* with no leading 0 byte. Accept this here. */
|
|
||||||
TEST_ASSERT( n_bytes == n_encoded_bytes ||
|
|
||||||
n_bytes == n_encoded_bytes + 1 );
|
|
||||||
if( n_bytes == n_encoded_bytes )
|
|
||||||
TEST_ASSERT( exported[n_encoded_bytes <= 127 ? 9 : 10] == 0x00 );
|
|
||||||
/* Sanity check: e must be 3 */
|
|
||||||
TEST_ASSERT( n_end[0] == 0x02 );
|
|
||||||
TEST_ASSERT( n_end[1] == 0x03 );
|
|
||||||
TEST_ASSERT( n_end[2] == 0x01 );
|
|
||||||
TEST_ASSERT( n_end[3] == 0x00 );
|
|
||||||
TEST_ASSERT( n_end[4] == 0x01 );
|
|
||||||
TEST_ASSERT( n_end[5] == 0x02 );
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_RSA_C */
|
|
||||||
#if defined(MBEDTLS_ECP_C)
|
|
||||||
if( PSA_KEY_TYPE_IS_ECC( type ) )
|
|
||||||
{
|
|
||||||
/* Sanity check: does this look like the beginning of a PKCS#8
|
|
||||||
* elliptic curve key pair? */
|
|
||||||
TEST_ASSERT( exported_length >= bits * 3 / 8 + 10 );
|
|
||||||
TEST_ASSERT( exported[0] == 0x30 );
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_ECP_C */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do something with the key according to its type and permitted usage. */
|
/* Do something with the key according to its type and permitted usage. */
|
||||||
if( ! exercise_key( slot, usage, alg ) )
|
if( ! exercise_key( slot, usage, alg ) )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
Loading…
Reference in a new issue