@@ -3380,31 +3380,29 @@ static bool ML_DSA_SIGGEN(const Span<const uint8_t> args[],
33803380 const Span<const uint8_t > context = args[4 ];
33813381 const Span<const uint8_t > extmu = args[5 ];
33823382
3383- using SignFunc = int (*)(const uint8_t *, uint8_t *, size_t *,
3384- const uint8_t *, size_t , const uint8_t *, size_t );
33853383 using SignInternalFunc = int (*)(const uint8_t *, uint8_t *, size_t *,
33863384 const uint8_t *, size_t ,
33873385 const uint8_t *, size_t , const uint8_t *);
33883386
33893387 // Group all related functions for each variant
33903388 struct MLDSA_functions {
33913389 void (*params_init)(ml_dsa_params*);
3392- SignFunc sign;
33933390 SignInternalFunc sign_internal;
33943391 SignInternalFunc extmu_sign_internal;
33953392 };
33963393
3397- // Select function set based on NID
3394+ // Select function set based on NID. We must use |ml_dsa_*_sign_internal| here,
3395+ // to account for the random inputs (rnd).
33983396 MLDSA_functions mldsa_funcs;
33993397 if (nid == NID_MLDSA44) {
3400- mldsa_funcs = {ml_dsa_44_params_init, ml_dsa_44_sign ,
3401- ml_dsa_44_sign_internal, ml_dsa_extmu_44_sign_internal};
3398+ mldsa_funcs = {ml_dsa_44_params_init, ml_dsa_44_sign_internal ,
3399+ ml_dsa_extmu_44_sign_internal};
34023400 } else if (nid == NID_MLDSA65) {
3403- mldsa_funcs = {ml_dsa_65_params_init, ml_dsa_65_sign ,
3404- ml_dsa_65_sign_internal, ml_dsa_extmu_65_sign_internal};
3401+ mldsa_funcs = {ml_dsa_65_params_init, ml_dsa_65_sign_internal ,
3402+ ml_dsa_extmu_65_sign_internal};
34053403 } else if (nid == NID_MLDSA87) {
3406- mldsa_funcs = {ml_dsa_87_params_init, ml_dsa_87_sign ,
3407- ml_dsa_87_sign_internal, ml_dsa_extmu_87_sign_internal};
3404+ mldsa_funcs = {ml_dsa_87_params_init, ml_dsa_87_sign_internal ,
3405+ ml_dsa_extmu_87_sign_internal};
34083406 } else {
34093407 return false ;
34103408 }
@@ -3415,12 +3413,8 @@ static bool ML_DSA_SIGGEN(const Span<const uint8_t> args[],
34153413 size_t signature_len = params.bytes ;
34163414 std::vector<uint8_t > signature (signature_len);
34173415
3418- if (!context.empty ()) {
3419- if (!mldsa_funcs.sign (sk.data (), signature.data (), &signature_len,
3420- msg.data (), msg.size (), context.data (), context.size ())) {
3421- return false ;
3422- }
3423- } else {
3416+ if (!extmu.empty ()) {
3417+ // Only signatureInterface: internal contains the externalMu field.
34243418 if (extmu.data ()[0 ] == 0 ) {
34253419 // generate the signatures raw sign mode
34263420 if (!mldsa_funcs.sign_internal (sk.data (), signature.data (), &signature_len,
@@ -3434,6 +3428,20 @@ static bool ML_DSA_SIGGEN(const Span<const uint8_t> args[],
34343428 return false ;
34353429 }
34363430 }
3431+ } else {
3432+ // |context| is unique to signatureInterface: external.
3433+ //
3434+ // Prepare |pre| exactly how |ml_dsa_sign| is doing. The maximum |context| size
3435+ // for ML-DSA is 255 bytes. We append a 0 and the size as two additional bytes
3436+ // before |context| to become the prefix string.
3437+ uint8_t pre [257 ];
3438+ pre [0 ] = 0 ;
3439+ pre [1 ] = context.size ();
3440+ OPENSSL_memcpy (pre + 2 , context.data (), context.size ());
3441+ if (!mldsa_funcs.sign_internal (sk.data (), signature.data (), &signature_len,
3442+ msg.data (), msg.size (), pre , 2 + context.size (), rnd.data ())) {
3443+ return false ;
3444+ }
34373445 }
34383446
34393447 return write_reply ({Span<const uint8_t >(signature)});
@@ -3476,12 +3484,8 @@ static bool ML_DSA_SIGVER(const Span<const uint8_t> args[], ReplyCallback write_
34763484 }
34773485
34783486 uint8_t reply[1 ] = {0 };
3479- if (!context.empty ()) {
3480- if (mldsa_funcs.verify (pk.data (), sig.data (), sig.size (), msg.data (),
3481- msg.size (), context.data (), context.size ())) {
3482- reply[0 ] = 1 ;
3483- }
3484- } else {
3487+ if (!extmu.empty ()) {
3488+ // Only signatureInterface: internal contains the externalMu field.
34853489 if (extmu.data ()[0 ] == 0 ) {
34863490 // verify the signatures raw sign mode
34873491 if (mldsa_funcs.verify_internal (pk.data (), sig.data (), sig.size (), msg.data (),
@@ -3495,6 +3499,12 @@ static bool ML_DSA_SIGVER(const Span<const uint8_t> args[], ReplyCallback write_
34953499 reply[0 ] = 1 ;
34963500 }
34973501 }
3502+ } else {
3503+ // |context| is unique to signatureInterface: external.
3504+ if (mldsa_funcs.verify (pk.data (), sig.data (), sig.size (), msg.data (),
3505+ msg.size (), context.data (), context.size ())) {
3506+ reply[0 ] = 1 ;
3507+ }
34983508 }
34993509
35003510 return write_reply ({Span<const uint8_t >(reply)});
0 commit comments