Skip to content

Commit 37222e1

Browse files
authored
Merge branch 'main' into implement-ec-cli
2 parents 6b751a0 + 822b016 commit 37222e1

File tree

16 files changed

+2369
-782
lines changed

16 files changed

+2369
-782
lines changed

crypto/evp_extra/p_kem_asn1.c

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -178,26 +178,45 @@ static int kem_priv_decode(EVP_PKEY *out, CBS *oid, CBS *params, CBS *key,
178178
return 0;
179179
}
180180

181-
// At the moment, we only support expandedKey format from
182-
// https://datatracker.ietf.org/doc/draft-ietf-lamps-kyber-certificates.
183-
// TODO(awslc): add support for "seed" and "both" formats.
184-
if (!CBS_peek_asn1_tag(key, CBS_ASN1_OCTETSTRING)) {
181+
// Support multiple ML-KEM private key formats from
182+
// https://datatracker.ietf.org/doc/draft-ietf-lamps-kyber-certificates/
183+
// Case 1: seed [0] OCTET STRING
184+
// Case 2: expandedKey OCTET STRING
185+
// Case 3: TODO: both SEQUENCE {seed, expandedKey}
186+
187+
if (CBS_peek_asn1_tag(key, CBS_ASN1_CONTEXT_SPECIFIC)) {
188+
// Case 1: seed [0] OCTET STRING
189+
CBS seed;
190+
if (!CBS_get_asn1(key, &seed, CBS_ASN1_CONTEXT_SPECIFIC)) {
191+
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
192+
return 0;
193+
}
194+
195+
if (CBS_len(&seed) != out->pkey.kem_key->kem->keygen_seed_len) {
196+
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
197+
return 0;
198+
}
199+
200+
return KEM_KEY_set_raw_keypair_from_seed(out->pkey.kem_key, &seed);
201+
} else if (CBS_peek_asn1_tag(key, CBS_ASN1_OCTETSTRING)) {
202+
// Case 2: expandedKey OCTET STRING
203+
CBS expanded_key;
204+
if (!CBS_get_asn1(key, &expanded_key, CBS_ASN1_OCTETSTRING)) {
205+
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
206+
return 0;
207+
}
208+
209+
if (CBS_len(&expanded_key) != out->pkey.kem_key->kem->secret_key_len) {
210+
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
211+
return 0;
212+
}
213+
214+
return KEM_KEY_set_raw_secret_key(out->pkey.kem_key, CBS_data(&expanded_key));
215+
} else {
216+
// Case 3: both SEQUENCE {seed, expandedKey} - not implemented yet
185217
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
186218
return 0;
187219
}
188-
189-
CBS expanded_key;
190-
if (!CBS_get_asn1(key, &expanded_key, CBS_ASN1_OCTETSTRING)) {
191-
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
192-
return 0;
193-
}
194-
195-
if (CBS_len(&expanded_key) != out->pkey.kem_key->kem->secret_key_len) {
196-
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
197-
return 0;
198-
}
199-
200-
return KEM_KEY_set_raw_secret_key(out->pkey.kem_key, CBS_data(&expanded_key));
201220
}
202221

203222
static int kem_priv_encode(CBB *out, const EVP_PKEY *pkey) {

crypto/evp_extra/p_kem_test.cc

Lines changed: 233 additions & 137 deletions
Large diffs are not rendered by default.

crypto/fipsmodule/kem/internal.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ int KEM_KEY_set_raw_secret_key(KEM_KEY *key, const uint8_t *in);
9898
int KEM_KEY_set_raw_key(KEM_KEY *key, const uint8_t *in_public,
9999
const uint8_t *in_secret);
100100

101+
// KEM_KEY_set_raw_keypair_from_seed function generates a keypair from the
102+
// given seed using the appropriate key generation function based on the
103+
// KEM variant, then allocates and sets both public and secret key buffers
104+
// within the given |key|.
105+
//
106+
// NOTE: The seed must be exactly 64 bytes for all ML-KEM variants.
107+
// The caller must ensure the seed CBS contains valid data.
108+
// |key->kem| must be initialized and |key->public_key| and
109+
// |key->secret_key| must both be NULL.
110+
int KEM_KEY_set_raw_keypair_from_seed(KEM_KEY *key, const CBS *seed);
111+
101112
#if defined(__cplusplus)
102113
} // extern C
103114
#endif

crypto/fipsmodule/kem/kem.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "../delocate.h"
88
#include "../ml_kem/ml_kem.h"
99
#include "internal.h"
10+
#include <openssl/bytestring.h>
11+
#include <openssl/err.h>
1012

1113
// https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
1214
// 2.16.840.1.101.3.4.4.1
@@ -306,3 +308,51 @@ int KEM_KEY_set_raw_key(KEM_KEY *key, const uint8_t *in_public,
306308

307309
return 1;
308310
}
311+
312+
int KEM_KEY_set_raw_keypair_from_seed(KEM_KEY *key, const CBS *seed) {
313+
if (key == NULL || seed == NULL || key->kem == NULL) {
314+
OPENSSL_PUT_ERROR(CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
315+
return 0;
316+
}
317+
318+
// Ensure key is uninitialized
319+
if (key->public_key != NULL || key->secret_key != NULL) {
320+
OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
321+
return 0;
322+
}
323+
324+
// Validate seed length - all ML-KEM variants use 64-byte seeds
325+
if (CBS_len(seed) != key->kem->keygen_seed_len) {
326+
OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
327+
return 0;
328+
}
329+
330+
// Allocate buffers for key generation
331+
uint8_t *public_key = OPENSSL_malloc(key->kem->public_key_len);
332+
uint8_t *secret_key = OPENSSL_malloc(key->kem->secret_key_len);
333+
334+
if (public_key == NULL || secret_key == NULL) {
335+
OPENSSL_free(public_key);
336+
OPENSSL_free(secret_key);
337+
return 0;
338+
}
339+
340+
size_t public_len = key->kem->public_key_len;
341+
size_t secret_len = key->kem->secret_key_len;
342+
343+
// Generate keypair from seed using the KEM method
344+
if (!key->kem->method->keygen_deterministic(public_key, &public_len,
345+
secret_key, &secret_len,
346+
CBS_data(seed))) {
347+
OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
348+
OPENSSL_free(public_key);
349+
OPENSSL_free(secret_key);
350+
return 0;
351+
}
352+
353+
// Set public and secret key
354+
key->public_key = public_key;
355+
key->secret_key = secret_key;
356+
357+
return 1;
358+
}

crypto/pem/pem_lib.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,11 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
679679
if (!BUF_MEM_grow(headerB, hl + i + 9)) {
680680
goto err;
681681
}
682-
if (strncmp(buf, "-----END ", 9) == 0) {
682+
// To resolve following error:
683+
// /home/runner/work/aws-lc-rs/aws-lc-rs/aws-lc-sys/aws-lc/crypto/pem/pem_lib.c:707:11: error: 'strncmp' of strings of length 1 and 9 and bound of 9 evaluates to nonzero [-Werror=string-compare]
684+
// 707 | if (strncmp(buf, "-----END ", 9) == 0) {
685+
// | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
686+
if (CRYPTO_memcmp(buf, "-----END ", 9) == 0) {
683687
nohead = 1;
684688
break;
685689
}
@@ -709,7 +713,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
709713
if (i != 65) {
710714
end = 1;
711715
}
712-
if (strncmp(buf, "-----END ", 9) == 0) {
716+
if (CRYPTO_memcmp(buf, "-----END ", 9) == 0) {
713717
break;
714718
}
715719
if (i > 65) {
@@ -744,7 +748,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
744748
bl = hl;
745749
}
746750
i = strlen(nameB->data);
747-
if ((strncmp(buf, "-----END ", 9) != 0) ||
751+
if ((CRYPTO_memcmp(buf, "-----END ", 9) != 0) ||
748752
(strncmp(nameB->data, &(buf[9]), i) != 0) ||
749753
(strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
750754
OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE);

tool-openssl/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ add_executable(
1010
crl.cc
1111
dgst.cc
1212
ec.cc
13+
pass_util.cc
1314
pkcs8.cc
1415
pkey.cc
1516
rehash.cc
@@ -90,6 +91,8 @@ if(BUILD_TESTING)
9091
dgst_test.cc
9192
ec.cc
9293
ec_test.cc
94+
pass_util.cc
95+
pass_util_test.cc
9396
pkcs8.cc
9497
pkcs8_test.cc
9598
pkey.cc

0 commit comments

Comments
 (0)