Skip to content

Commit 4d69cf1

Browse files
authored
Merge pull request #13 from Patater/pubkey-format
Simplify RSA and EC public key formats
2 parents 0b6b871 + 21fec0c commit 4d69cf1

File tree

6 files changed

+288
-299
lines changed

6 files changed

+288
-299
lines changed

include/psa/crypto.h

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,32 @@ psa_status_t psa_export_key(psa_key_handle_t handle,
448448
* The output of this function can be passed to psa_import_key() to
449449
* create an object that is equivalent to the public key.
450450
*
451-
* The format is the DER representation defined by RFC 5280 as
452-
* `SubjectPublicKeyInfo`, with the `subjectPublicKey` format
451+
* This specification supports a single format for each key type.
452+
* Implementations may support other formats as long as the standard
453+
* format is supported. Implementations that support other formats
454+
* should ensure that the formats are clearly unambiguous so as to
455+
* minimize the risk that an invalid input is accidentally interpreted
456+
* according to a different format.
457+
*
458+
* For standard key types, the output format is as follows:
459+
* - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of
460+
* the representation defined by RFC 3279 §2.3.1 as `RSAPublicKey`.
461+
* ```
462+
* RSAPublicKey ::= SEQUENCE {
463+
* modulus INTEGER, -- n
464+
* publicExponent INTEGER } -- e
465+
* ```
466+
* - For elliptic curve public keys (key types for which
467+
* #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed
468+
* representation defined by SEC1 §2.3.3 as the content of an ECPoint:
469+
* Let `m` be the bit size associated with the curve, i.e. the bit size of
470+
* `q` for a curve over `F_q`. The representation consists of:
471+
* - The byte 0x04;
472+
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
473+
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
474+
*
475+
* For other public key types, the format is the DER representation defined by
476+
* RFC 5280 as `SubjectPublicKeyInfo`, with the `subjectPublicKey` format
453477
* specified below.
454478
* ```
455479
* SubjectPublicKeyInfo ::= SEQUENCE {
@@ -459,21 +483,6 @@ psa_status_t psa_export_key(psa_key_handle_t handle,
459483
* algorithm OBJECT IDENTIFIER,
460484
* parameters ANY DEFINED BY algorithm OPTIONAL }
461485
* ```
462-
*
463-
* - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY),
464-
* the `subjectPublicKey` format is defined by RFC 3279 §2.3.1 as
465-
* `RSAPublicKey`,
466-
* with the OID `rsaEncryption`,
467-
* and with the parameters `NULL`.
468-
* ```
469-
* pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
470-
* rsadsi(113549) pkcs(1) 1 }
471-
* rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
472-
*
473-
* RSAPublicKey ::= SEQUENCE {
474-
* modulus INTEGER, -- n
475-
* publicExponent INTEGER } -- e
476-
* ```
477486
* - For DSA public keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY),
478487
* the `subjectPublicKey` format is defined by RFC 3279 §2.3.2 as
479488
* `DSAPublicKey`,
@@ -489,30 +498,6 @@ psa_status_t psa_export_key(psa_key_handle_t handle,
489498
* g INTEGER }
490499
* DSAPublicKey ::= INTEGER -- public key, Y
491500
* ```
492-
* - For elliptic curve public keys (key types for which
493-
* #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true),
494-
* the `subjectPublicKey` format is defined by RFC 3279 §2.3.5 as
495-
* `ECPoint`, which contains the uncompressed
496-
* representation defined by SEC1 §2.3.3.
497-
* The OID is `id-ecPublicKey`,
498-
* and the parameters must be given as a `namedCurve` OID as specified in
499-
* RFC 5480 §2.1.1.1 or other applicable standards.
500-
* ```
501-
* ansi-X9-62 OBJECT IDENTIFIER ::=
502-
* { iso(1) member-body(2) us(840) 10045 }
503-
* id-public-key-type OBJECT IDENTIFIER ::= { ansi-X9.62 2 }
504-
* id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
505-
*
506-
* ECPoint ::= ...
507-
* -- first 8 bits: 0x04;
508-
* -- then x_P as a `ceiling(m/8)`-byte string, big endian;
509-
* -- then y_P as a `ceiling(m/8)`-byte string, big endian;
510-
* -- where `m` is the bit size associated with the curve,
511-
* -- i.e. the bit size of `q` for a curve over `F_q`.
512-
*
513-
* EcpkParameters ::= CHOICE { -- other choices are not allowed
514-
* namedCurve OBJECT IDENTIFIER }
515-
* ```
516501
*
517502
* \param handle Handle to the key to export.
518503
* \param[out] data Buffer where the key data is to be written.
@@ -2156,19 +2141,28 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
21562141
* The resulting generator always has the maximum capacity permitted by
21572142
* the algorithm.
21582143
*
2159-
* \param[in,out] generator The generator object to set up. It must have
2160-
* been initialized as per the documentation for
2161-
* #psa_crypto_generator_t and not yet in use.
2162-
* \param private_key Handle to the private key to use.
2163-
* \param[in] peer_key Public key of the peer. It must be
2164-
* in the same format that psa_import_key()
2165-
* accepts. The standard formats for public
2166-
* keys are documented in the documentation
2167-
* of psa_export_public_key().
2168-
* \param peer_key_length Size of \p peer_key in bytes.
2169-
* \param alg The key agreement algorithm to compute
2170-
* (\c PSA_ALG_XXX value such that
2171-
* #PSA_ALG_IS_KEY_AGREEMENT(\p alg) is true).
2144+
* \param[in,out] generator The generator object to set up. It must have been
2145+
* initialized as per the documentation for
2146+
* #psa_crypto_generator_t and not yet in use.
2147+
* \param private_key Handle to the private key to use.
2148+
* \param[in] peer_key Public key of the peer. The peer key must be in the
2149+
* same format that psa_import_key() accepts for the
2150+
* public key type corresponding to the type of
2151+
* \p private_key. That is, this function performs the
2152+
* equivalent of
2153+
* `psa_import_key(internal_public_key_handle,
2154+
* PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(private_key_type),
2155+
* peer_key, peer_key_length)` where
2156+
* `private_key_type` is the type of \p private_key.
2157+
* For example, for EC keys, this means that \p
2158+
* peer_key is interpreted as a point on the curve
2159+
* that the private key is associated with. The
2160+
* standard formats for public keys are documented in
2161+
* the documentation of psa_export_public_key().
2162+
* \param peer_key_length Size of \p peer_key in bytes.
2163+
* \param alg The key agreement algorithm to compute
2164+
* (\c PSA_ALG_XXX value such that
2165+
* #PSA_ALG_IS_KEY_AGREEMENT(\p alg) is true).
21722166
*
21732167
* \retval #PSA_SUCCESS
21742168
* Success.

include/psa/crypto_sizes.h

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -417,25 +417,16 @@
417417
/* Maximum size of the export encoding of an RSA public key.
418418
* Assumes that the public exponent is less than 2^32.
419419
*
420-
* SubjectPublicKeyInfo ::= SEQUENCE {
421-
* algorithm AlgorithmIdentifier,
422-
* subjectPublicKey BIT STRING } -- contains RSAPublicKey
423-
* AlgorithmIdentifier ::= SEQUENCE {
424-
* algorithm OBJECT IDENTIFIER,
425-
* parameters NULL }
426420
* RSAPublicKey ::= SEQUENCE {
427421
* modulus INTEGER, -- n
428422
* publicExponent INTEGER } -- e
429423
*
430-
* - 3 * 4 bytes of SEQUENCE overhead;
431-
* - 1 + 1 + 9 bytes of algorithm (RSA OID);
432-
* - 2 bytes of NULL;
433-
* - 4 bytes of BIT STRING overhead;
424+
* - 4 bytes of SEQUENCE overhead;
434425
* - n : INTEGER;
435426
* - 7 bytes for the public exponent.
436427
*/
437428
#define PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) \
438-
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 36)
429+
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 11)
439430

440431
/* Maximum size of the export encoding of an RSA key pair.
441432
* Assumes thatthe public exponent is less than 2^32 and that the size
@@ -502,26 +493,16 @@
502493

503494
/* Maximum size of the export encoding of an ECC public key.
504495
*
505-
* SubjectPublicKeyInfo ::= SEQUENCE {
506-
* algorithm AlgorithmIdentifier,
507-
* subjectPublicKey BIT STRING } -- contains ECPoint
508-
* AlgorithmIdentifier ::= SEQUENCE {
509-
* algorithm OBJECT IDENTIFIER,
510-
* parameters OBJECT IDENTIFIER } -- namedCurve
511-
* ECPoint ::= ...
512-
* -- first 8 bits: 0x04;
513-
* -- then x_P as a `ceiling(m/8)`-byte string, big endian;
514-
* -- then y_P as a `ceiling(m/8)`-byte string, big endian;
515-
* -- where `m` is the bit size associated with the curve.
516-
*
517-
* - 2 * 4 bytes of SEQUENCE overhead;
518-
* - 1 + 1 + 7 bytes of algorithm (id-ecPublicKey OID);
519-
* - 1 + 1 + 12 bytes of namedCurve OID;
520-
* - 4 bytes of BIT STRING overhead;
521-
* - 1 byte + 2 * point size in ECPoint.
496+
* The representation of an ECC public key is:
497+
* - The byte 0x04;
498+
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
499+
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
500+
* - where m is the bit size associated with the curve.
501+
*
502+
* - 1 byte + 2 * point size.
522503
*/
523504
#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \
524-
(2 * PSA_BITS_TO_BYTES(key_bits) + 36)
505+
(2 * PSA_BITS_TO_BYTES(key_bits) + 1)
525506

526507
/* Maximum size of the export encoding of an ECC key pair.
527508
*

0 commit comments

Comments
 (0)