-
Notifications
You must be signed in to change notification settings - Fork 54
Reject invalid API inputs before unsafe work #1231
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -915,6 +915,7 @@ int mld_sign_signature_internal(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen, | |
| uint8_t *rho, *tr, *key, *mu, *rhoprime; | ||
| uint16_t nonce = 0; | ||
| const uint16_t nonce_limit = mld_get_max_signing_attempts(); | ||
|
|
||
| MLD_ALLOC(seedbuf, uint8_t, | ||
| 2 * MLDSA_SEEDBYTES + MLDSA_TRBYTES + 2 * MLDSA_CRHBYTES, context); | ||
| MLD_ALLOC(mat, mld_polymat, 1, context); | ||
|
|
@@ -929,6 +930,12 @@ int mld_sign_signature_internal(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen, | |
| goto cleanup; | ||
| } | ||
|
|
||
| if (externalmu && mlen != MLDSA_CRHBYTES) | ||
| { | ||
| ret = MLD_ERR_FAIL; | ||
| goto cleanup; | ||
| } | ||
|
|
||
| rho = seedbuf; | ||
| tr = rho + MLDSA_SEEDBYTES; | ||
| key = tr + MLDSA_TRBYTES; | ||
|
|
@@ -1052,6 +1059,7 @@ int mld_sign_signature(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen, | |
| { | ||
| size_t pre_len; | ||
| int ret; | ||
|
|
||
| MLD_ALLOC(pre, uint8_t, MLD_DOMAIN_SEPARATION_MAX_BYTES, context); | ||
| MLD_ALLOC(rnd, uint8_t, MLDSA_RNDBYTES, context); | ||
|
|
||
|
|
@@ -1061,6 +1069,12 @@ int mld_sign_signature(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen, | |
| goto cleanup; | ||
| } | ||
|
|
||
| if (ctxlen > 255 || (ctx == NULL && ctxlen != 0)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove the |
||
| { | ||
| ret = MLD_ERR_FAIL; | ||
| goto cleanup; | ||
| } | ||
|
|
||
| /* Prepare domain separation prefix for pure ML-DSA */ | ||
| pre_len = mld_prepare_domain_separation_prefix(pre, NULL, 0, ctx, ctxlen, | ||
| MLD_PREHASH_NONE); | ||
|
|
@@ -1204,7 +1218,7 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen, | |
| goto cleanup; | ||
| } | ||
|
|
||
| if (siglen != MLDSA_CRYPTO_BYTES) | ||
| if (siglen != MLDSA_CRYPTO_BYTES || (externalmu && mlen != MLDSA_CRHBYTES)) | ||
| { | ||
| ret = MLD_ERR_FAIL; | ||
| goto cleanup; | ||
|
|
@@ -1320,6 +1334,12 @@ int mld_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, | |
| size_t pre_len; | ||
| int ret; | ||
|
|
||
| if (ctxlen > 255 || (ctx == NULL && ctxlen != 0)) | ||
| { | ||
| ret = MLD_ERR_FAIL; | ||
| goto cleanup; | ||
| } | ||
|
|
||
| pre_len = mld_prepare_domain_separation_prefix(pre, NULL, 0, ctx, ctxlen, | ||
| MLD_PREHASH_NONE); | ||
| if (pre_len == 0) | ||
|
|
@@ -1411,6 +1431,12 @@ int mld_sign_signature_pre_hash_internal( | |
| size_t pre_len; | ||
| int ret; | ||
|
|
||
| if (ctxlen > 255 || (ctx == NULL && ctxlen != 0)) | ||
| { | ||
| ret = MLD_ERR_FAIL; | ||
| goto cleanup; | ||
| } | ||
|
|
||
| pre_len = mld_prepare_domain_separation_prefix(pre, ph, phlen, ctx, ctxlen, | ||
| hashalg); | ||
| if (pre_len == 0) | ||
|
|
@@ -1453,6 +1479,12 @@ int mld_sign_verify_pre_hash_internal( | |
| size_t pre_len; | ||
| int ret; | ||
|
|
||
| if (ctxlen > 255 || (ctx == NULL && ctxlen != 0)) | ||
| { | ||
| ret = MLD_ERR_FAIL; | ||
| goto cleanup; | ||
| } | ||
|
|
||
| pre_len = mld_prepare_domain_separation_prefix(pre, ph, phlen, ctx, ctxlen, | ||
| hashalg); | ||
| if (pre_len == 0) | ||
|
|
@@ -1607,7 +1639,7 @@ size_t mld_prepare_domain_separation_prefix( | |
| uint8_t prefix[MLD_DOMAIN_SEPARATION_MAX_BYTES], const uint8_t *ph, | ||
| size_t phlen, const uint8_t *ctx, size_t ctxlen, int hashalg) | ||
| { | ||
| if (ctxlen > 255) | ||
| if (ctxlen > 255 || (ctx == NULL && ctxlen != 0)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer input validation to happen at the top-level API, even if it means a bit of code-duplication. |
||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -253,7 +253,7 @@ __contract__( | |
| * @param[in] m Pointer to message to be signed. | ||
| * @param mlen Length of message. | ||
| * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0. | ||
| * @param ctxlen Length of context string. Should be <= 255. | ||
| * @param ctxlen Length of context string. Must be <= 255. | ||
| * @param[in] sk Bit-packed secret key. | ||
| * @param context Application context. Only present when | ||
| * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by | ||
|
|
@@ -343,8 +343,8 @@ __contract__( | |
| * @param[out] smlen Pointer to output length of signed message. | ||
| * @param[in] m Pointer to message to be signed. | ||
| * @param mlen Length of message. | ||
| * @param[in] ctx Pointer to context string. | ||
| * @param ctxlen Length of context string. | ||
| * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0. | ||
| * @param ctxlen Length of context string. Must be <= 255. | ||
| * @param[in] sk Bit-packed secret key. | ||
| * @param context Application context. Only present when | ||
| * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by | ||
|
|
@@ -371,7 +371,7 @@ __contract__( | |
| requires(memory_no_alias(smlen, sizeof(size_t))) | ||
| requires(m == sm || memory_no_alias(m, mlen)) | ||
| requires(ctxlen <= MLD_MAX_BUFFER_SIZE) | ||
| requires(memory_no_alias(ctx, ctxlen)) | ||
| requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure if this needed. My understanding was that memory_no_alias() does permit NULL if the length is zero bytes. |
||
| requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES)) | ||
| assigns(memory_slice(sm, MLDSA_CRYPTO_BYTES + mlen)) | ||
| assigns(object_whole(smlen)) | ||
|
|
@@ -787,8 +787,8 @@ __contract__( | |
| * @param[in] ph Pointer to pre-hashed message (ignored for pure | ||
| * ML-DSA). | ||
| * @param phlen Length of pre-hashed message (ignored for pure ML-DSA). | ||
| * @param[in] ctx Pointer to context string (may be NULL). | ||
| * @param ctxlen Length of context string. | ||
| * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0. | ||
| * @param ctxlen Length of context string. Must be <= 255. | ||
| * @param hashalg Hash algorithm constant (MLD_PREHASH_NONE for pure | ||
| * ML-DSA, or MLD_PREHASH_* for HashML-DSA). | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check must happen after the allocations for strict C90 compliance. Which has the benefit that we can reuse the cleanup section.