Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExternalMu mode for pre-hash ML-DSA #2113

Merged
merged 36 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5abd396
ml-dsa extmu
jakemas Jan 10, 2025
00b3ba1
CR fixes from nevine and will
jakemas Jan 13, 2025
0461f48
spacing nits
jakemas Jan 13, 2025
21006fd
evp documentation
jakemas Jan 13, 2025
9f17f86
Merge branch 'main' into extmu-ml-dsa
jakemas Jan 13, 2025
7823f93
removed use of internal functions in test file
jakemas Jan 13, 2025
7baa8c1
spacing nits
jakemas Jan 13, 2025
9de6f9d
mem leak in test code
jakemas Jan 13, 2025
dddd501
duplicated line
jakemas Jan 13, 2025
bd4e629
added negative testing for extmu
jakemas Jan 13, 2025
9a90332
added ACVP access for extmu internal and KAT framework
jakemas Jan 14, 2025
cb40bdc
spacing nit
jakemas Jan 14, 2025
ba50e2c
Merge branch 'main' into extmu-ml-dsa
jakemas Jan 14, 2025
ba1856b
CR fixes
jakemas Jan 14, 2025
255aa97
Merge branch 'extmu-ml-dsa' of github.com:jakemas/aws-lc into extmu-m…
jakemas Jan 14, 2025
89d4744
spotted typo
jakemas Jan 14, 2025
49580d6
updated message names to mu
jakemas Jan 14, 2025
a97e54b
Merge branch 'main' into extmu-ml-dsa
jakemas Jan 15, 2025
318f0c1
internal naming
jakemas Jan 15, 2025
6d214b5
readme updates
jakemas Jan 15, 2025
195779c
readme update
jakemas Jan 15, 2025
75ccaf5
Merge branch 'main' into extmu-ml-dsa
jakemas Jan 16, 2025
3d98fb6
remove KAT
jakemas Jan 16, 2025
b347ee6
added source files
jakemas Jan 16, 2025
3b6e302
updated gensrc
jakemas Jan 16, 2025
2f8729a
update readme to discuss KAT
jakemas Jan 16, 2025
ce4f764
update gen src
jakemas Jan 16, 2025
957523e
added ACVP test vectors
jakemas Jan 16, 2025
76a71f1
update readme
jakemas Jan 16, 2025
807aca4
Merge branch 'main' into extmu-ml-dsa
jakemas Jan 17, 2025
201b096
update internal name
jakemas Jan 17, 2025
6762c2a
Merge branch 'extmu-ml-dsa' of github.com:jakemas/aws-lc into extmu-m…
jakemas Jan 17, 2025
0dfc1f2
typo
jakemas Jan 17, 2025
e56a143
missed space
jakemas Jan 17, 2025
49d0b08
missed space
jakemas Jan 17, 2025
36e9ae2
Merge branch 'main' into extmu-ml-dsa
jakemas Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 85 additions & 19 deletions crypto/evp_extra/p_pqdsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ static int pkey_pqdsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
return 1;
}

static int pkey_pqdsa_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig,
size_t *sig_len, const uint8_t *message,
size_t message_len) {
static int pkey_pqdsa_sign_generic(EVP_PKEY_CTX *ctx, uint8_t *sig,
size_t *sig_len, const uint8_t *message,
size_t message_len, int sign_digest) {
GUARD_PTR(sig_len);

PQDSA_PKEY_CTX *dctx = ctx->data;
const PQDSA *pqdsa = dctx->pqdsa;
if (pqdsa == NULL) {
Expand Down Expand Up @@ -95,16 +96,50 @@ static int pkey_pqdsa_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig,
return 0;
}

if (!pqdsa->method->pqdsa_sign(key->private_key, sig, sig_len, message, message_len, NULL, 0)) {
OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
return 0;
// |sign_digest| is a flag we use to indicate that the message to be signed has
// already been pre-processed and hashed into a message digest.
// When the PQDSA algorithm is selected as ML-DSA (i.e., NID_MLDSA{44/65/87}),
// |sign_digest| indicates that the input is |mu| which is the result of a SHAKE256
// hash of the associated public key concatenated with a zero byte to indicate
// pure-mode, the context string length, the contents of the context string,
// and the input message in this order e.g.
// mu = SHAKE256(SHAKE256(pk) || 0 || |ctx| || ctx || M).

// RAW sign mode
if (!sign_digest) {
if (!pqdsa->method->pqdsa_sign_message(key->private_key, sig, sig_len, message, message_len, NULL, 0)) {
OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
return 0;
}
}
// DIGEST sign mode
else {
if (!pqdsa->method->pqdsa_sign(key->private_key, sig, sig_len, message, message_len)) {
OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
return 0;
}
}

return 1;
}

static int pkey_pqdsa_verify_signature(EVP_PKEY_CTX *ctx, const uint8_t *sig,
size_t sig_len, const uint8_t *message,
size_t message_len) {
// DIGEST signing
static int pkey_pqdsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig,
size_t *sig_len, const uint8_t *digest,
size_t digest_len) {
return pkey_pqdsa_sign_generic(ctx, sig, sig_len, digest, digest_len, 1);
}

// RAW message signing
static int pkey_pqdsa_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig,
size_t *sig_len, const uint8_t *message,
size_t message_len) {
return pkey_pqdsa_sign_generic(ctx, sig, sig_len, message, message_len, 0);
}

static int pkey_pqdsa_verify_generic(EVP_PKEY_CTX *ctx, const uint8_t *sig,
size_t sig_len, const uint8_t *message,
size_t message_len, int verify_digest) {
PQDSA_PKEY_CTX *dctx = ctx->data;
const PQDSA *pqdsa = dctx->pqdsa;

Expand All @@ -126,15 +161,49 @@ static int pkey_pqdsa_verify_signature(EVP_PKEY_CTX *ctx, const uint8_t *sig,

PQDSA_KEY *key = ctx->pkey->pkey.pqdsa_key;

if (sig_len != pqdsa->signature_len ||
!pqdsa->method->pqdsa_verify(key->public_key, sig, sig_len, message, message_len, NULL, 0)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE);
return 0;
// |verify_digest| is a flag we use to indicate that the message to be verified has
// already been pre-processed and hashed into a message digest.
// When the PQDSA algorithm is selected as ML-DSA (i.e., NID_MLDSA{44/65/87}),
// |verify_digest| indicates that the input is |mu| which is the result of a SHAKE256
// hash of the associated public key concatenated with a zero byte to indicate
// pure-mode, the context string length, the contents of the context string,
// and the input message in this order e.g.
// mu = SHAKE256(SHAKE256(pk) || 0 || |ctx| || ctx || M).

// RAW verify mode
if(!verify_digest) {
if (sig_len != pqdsa->signature_len ||
!pqdsa->method->pqdsa_verify_message(key->public_key, sig, sig_len, message, message_len, NULL, 0)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE);
return 0;
}
}
// DIGEST verify mode
else {
if (sig_len != pqdsa->signature_len ||
!pqdsa->method->pqdsa_verify(key->public_key, sig, sig_len, message, message_len)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE);
return 0;
}
}

return 1;
}

// DIGEST verification
static int pkey_pqdsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig,
size_t sig_len, const uint8_t *message,
size_t message_len) {
return pkey_pqdsa_verify_generic(ctx, sig, sig_len, message, message_len, 1);
}

// RAW message verification
static int pkey_pqdsa_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig,
size_t sig_len, const uint8_t *message,
size_t message_len) {
return pkey_pqdsa_verify_generic(ctx, sig, sig_len, message, message_len, 0);
}

// Additional PQDSA specific EVP functions.

// This function sets pqdsa parameters defined by |nid| in |pkey|.
Expand Down Expand Up @@ -266,11 +335,11 @@ const EVP_PKEY_METHOD pqdsa_pkey_meth = {
pkey_pqdsa_cleanup,
pkey_pqdsa_keygen,
NULL,
NULL,
pkey_pqdsa_sign,
pkey_pqdsa_sign_message,
NULL,
NULL,
pkey_pqdsa_verify_signature,
pkey_pqdsa_verify,
pkey_pqdsa_verify_message,
NULL,
NULL,
NULL,
Expand All @@ -283,6 +352,3 @@ const EVP_PKEY_METHOD pqdsa_pkey_meth = {
NULL,
NULL,
};



Loading
Loading