Skip to content

Commit 56ebad6

Browse files
[Cherry-pick FIPS 2025] Add support for external contexts in ML-DSA ACVP (#2881)
cherry picked from commit on main: 7c02cb3 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.
1 parent 613f0fd commit 56ebad6

File tree

4 files changed

+104
-92
lines changed

4 files changed

+104
-92
lines changed

util/fipstools/acvp/acvptool/subprocess/ml_dsa.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func processMlDsaSigGen(vectors json.RawMessage, m Transactable) (interface{}, e
150150

151151
for _, test := range group.Tests {
152152
results, err := m.Transact("ML-DSA/"+group.ParameterSet+"/sigGen",
153-
1, test.SK, test.Message, test.MU, test.RND, boolToBytes(group.ExternalMu))
153+
1, test.SK, test.Message, test.MU, test.RND, test.Context, boolToBytes(group.ExternalMu))
154154
if err != nil {
155155
return nil, err
156156
}
@@ -216,7 +216,7 @@ func processMlDsaSigVer(vectors json.RawMessage, m Transactable) (interface{}, e
216216

217217
for _, test := range group.Tests {
218218
results, err := m.Transact("ML-DSA/"+group.ParameterSet+"/sigVer", 1,
219-
test.Signature, test.PK, test.Message, test.MU, boolToBytes(group.ExternalMu))
219+
test.Signature, test.PK, test.Message, test.MU, test.Context, boolToBytes(group.ExternalMu))
220220
if err != nil {
221221
return nil, err
222222
}
84 Bytes
Binary file not shown.
44.3 KB
Binary file not shown.

util/fipstools/acvp/modulewrapper/modulewrapper.cc

Lines changed: 102 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,10 @@ static bool GetConfig(const Span<const uint8_t> args[],
14471447
true,
14481448
false
14491449
],
1450-
"signatureInterfaces": ["internal"]
1450+
"signatureInterfaces": [
1451+
"internal",
1452+
"external"
1453+
]
14511454
},{
14521455
"algorithm": "ML-DSA",
14531456
"mode": "sigVer",
@@ -1473,7 +1476,10 @@ static bool GetConfig(const Span<const uint8_t> args[],
14731476
true,
14741477
false
14751478
],
1476-
"signatureInterfaces": ["internal"]
1479+
"signatureInterfaces": [
1480+
"internal",
1481+
"external"
1482+
]
14771483
}])";
14781484
return write_reply({Span<const uint8_t>(
14791485
reinterpret_cast<const uint8_t *>(kConfig), sizeof(kConfig) - 1)});
@@ -3313,60 +3319,60 @@ static bool ML_DSA_SIGGEN(const Span<const uint8_t> args[],
33133319
const Span<const uint8_t> msg = args[1];
33143320
const Span<const uint8_t> mu = args[2];
33153321
const Span<const uint8_t> rnd = args[3];
3316-
const Span<const uint8_t> extmu = args[4];
3317-
3318-
ml_dsa_params params;
3322+
const Span<const uint8_t> context = args[4];
3323+
const Span<const uint8_t> extmu = args[5];
3324+
3325+
using SignFunc = int (*)(const uint8_t*, uint8_t*, size_t*,
3326+
const uint8_t*, size_t, const uint8_t*, size_t);
3327+
using SignInternalFunc = int (*)(const uint8_t*, uint8_t*, size_t*,
3328+
const uint8_t*, size_t,
3329+
const uint8_t*, size_t, const uint8_t*);
3330+
3331+
// Group all related functions for each variant
3332+
struct MLDSA_functions {
3333+
void (*params_init)(ml_dsa_params*);
3334+
SignFunc sign;
3335+
SignInternalFunc sign_internal;
3336+
SignInternalFunc extmu_sign_internal;
3337+
};
3338+
3339+
// Select function set based on NID
3340+
MLDSA_functions mldsa_funcs;
33193341
if (nid == NID_MLDSA44) {
3320-
ml_dsa_44_params_init(&params);
3321-
}
3322-
else if (nid == NID_MLDSA65) {
3323-
ml_dsa_65_params_init(&params);
3324-
}
3325-
else if (nid == NID_MLDSA87) {
3326-
ml_dsa_87_params_init(&params);
3342+
mldsa_funcs = {ml_dsa_44_params_init, ml_dsa_44_sign,
3343+
ml_dsa_44_sign_internal, ml_dsa_extmu_44_sign_internal};
3344+
} else if (nid == NID_MLDSA65) {
3345+
mldsa_funcs = {ml_dsa_65_params_init, ml_dsa_65_sign,
3346+
ml_dsa_65_sign_internal, ml_dsa_extmu_65_sign_internal};
3347+
} else if (nid == NID_MLDSA87) {
3348+
mldsa_funcs = {ml_dsa_87_params_init, ml_dsa_87_sign,
3349+
ml_dsa_87_sign_internal, ml_dsa_extmu_87_sign_internal};
3350+
} else {
3351+
return false;
33273352
}
33283353

3354+
ml_dsa_params params;
3355+
mldsa_funcs.params_init(&params);
3356+
33293357
size_t signature_len = params.bytes;
33303358
std::vector<uint8_t> signature(signature_len);
33313359

3332-
// generate the signatures raw sign mode
3333-
if (extmu.data()[0] == 0) {
3334-
if (nid == NID_MLDSA44) {
3335-
if (!ml_dsa_44_sign_internal(sk.data(), signature.data(), &signature_len,
3336-
msg.data(), msg.size(), nullptr, 0, rnd.data())) {
3337-
return false;
3338-
}
3339-
}
3340-
else if (nid == NID_MLDSA65) {
3341-
if (!ml_dsa_65_sign_internal(sk.data(), signature.data(), &signature_len,
3342-
msg.data(), msg.size(), nullptr, 0, rnd.data())) {
3343-
return false;
3344-
}
3345-
}
3346-
else if (nid == NID_MLDSA87) {
3347-
if (!ml_dsa_87_sign_internal(sk.data(), signature.data(), &signature_len,
3348-
msg.data(), msg.size(), nullptr, 0, rnd.data())) {
3349-
return false;
3350-
}
3351-
}
3352-
}
3353-
// generate the signatures digest sign mode (externalmu)
3354-
else {
3355-
if (nid == NID_MLDSA44) {
3356-
if (!ml_dsa_extmu_44_sign_internal(sk.data(), signature.data(), &signature_len,
3357-
mu.data(), mu.size(), nullptr, 0, rnd.data())) {
3358-
return false;
3359-
}
3360+
if (!context.empty()) {
3361+
if (!mldsa_funcs.sign(sk.data(), signature.data(), &signature_len,
3362+
msg.data(), msg.size(), context.data(), context.size())) {
3363+
return false;
33603364
}
3361-
else if (nid == NID_MLDSA65) {
3362-
if (!ml_dsa_extmu_65_sign_internal(sk.data(), signature.data(), &signature_len,
3363-
mu.data(), mu.size(), nullptr, 0, rnd.data())) {
3365+
} else {
3366+
if (extmu.data()[0] == 0) {
3367+
// generate the signatures raw sign mode
3368+
if (!mldsa_funcs.sign_internal(sk.data(), signature.data(), &signature_len,
3369+
msg.data(), msg.size(), nullptr, 0, rnd.data())) {
33643370
return false;
33653371
}
3366-
}
3367-
else if (nid == NID_MLDSA87) {
3368-
if (!ml_dsa_extmu_87_sign_internal(sk.data(), signature.data(), &signature_len,
3369-
mu.data(), mu.size(), nullptr, 0, rnd.data())) {
3372+
} else {
3373+
// generate the signatures digest sign mode (externalmu)
3374+
if (!mldsa_funcs.extmu_sign_internal(sk.data(), signature.data(), &signature_len,
3375+
mu.data(), mu.size(), nullptr, 0, rnd.data())) {
33703376
return false;
33713377
}
33723378
}
@@ -3381,52 +3387,58 @@ static bool ML_DSA_SIGVER(const Span<const uint8_t> args[], ReplyCallback write_
33813387
const Span<const uint8_t> pk = args[1];
33823388
const Span<const uint8_t> msg = args[2];
33833389
const Span<const uint8_t> mu = args[3];
3384-
const Span<const uint8_t> extmu = args[4];
3390+
const Span<const uint8_t> context = args[4];
3391+
const Span<const uint8_t> extmu = args[5];
3392+
3393+
using VerifyFunc = int (*)(const uint8_t*, const uint8_t*, size_t,
3394+
const uint8_t*, size_t, const uint8_t*, size_t);
3395+
using VerifyInternalFunc = int (*)(const uint8_t*, const uint8_t*, size_t,
3396+
const uint8_t*, size_t, const uint8_t*, size_t);
3397+
3398+
// Group all related functions for each variant
3399+
struct MLDSA_functions {
3400+
VerifyFunc verify;
3401+
VerifyInternalFunc verify_internal;
3402+
VerifyInternalFunc extmu_verify_internal;
3403+
};
3404+
3405+
// Select function set based on NID
3406+
MLDSA_functions mldsa_funcs;
3407+
if (nid == NID_MLDSA44) {
3408+
mldsa_funcs = {ml_dsa_44_verify, ml_dsa_44_verify_internal,
3409+
ml_dsa_extmu_44_verify_internal};
3410+
} else if (nid == NID_MLDSA65) {
3411+
mldsa_funcs = {ml_dsa_65_verify, ml_dsa_65_verify_internal,
3412+
ml_dsa_extmu_65_verify_internal};
3413+
} else if (nid == NID_MLDSA87) {
3414+
mldsa_funcs = {ml_dsa_87_verify, ml_dsa_87_verify_internal,
3415+
ml_dsa_extmu_87_verify_internal};
3416+
} else {
3417+
return false;
3418+
}
33853419

33863420
uint8_t reply[1] = {0};
3387-
3388-
// verify the signatures raw sign mode
3389-
if (extmu.data()[0] == 0) {
3390-
if (nid == NID_MLDSA44) {
3391-
if (ml_dsa_44_verify_internal(pk.data(), sig.data(), sig.size(), msg.data(),
3392-
msg.size(), nullptr, 0)) {
3393-
reply[0] = 1;
3394-
}
3421+
if (!context.empty()) {
3422+
if (mldsa_funcs.verify(pk.data(), sig.data(), sig.size(), msg.data(),
3423+
msg.size(), context.data(), context.size())) {
3424+
reply[0] = 1;
33953425
}
3396-
else if (nid == NID_MLDSA65) {
3397-
if (ml_dsa_65_verify_internal(pk.data(), sig.data(), sig.size(), msg.data(),
3398-
msg.size(), nullptr, 0)) {
3399-
reply[0] = 1;
3400-
}
3401-
}
3402-
else if (nid == NID_MLDSA87) {
3403-
if (ml_dsa_87_verify_internal(pk.data(), sig.data(), sig.size(), msg.data(),
3404-
msg.size(), nullptr, 0)) {
3405-
reply[0] = 1;
3406-
}
3407-
}
3408-
}
3409-
// verify the signatures digest sign mode (externalmu)
3410-
else{
3411-
if (nid == NID_MLDSA44) {
3412-
if (ml_dsa_extmu_44_verify_internal(pk.data(), sig.data(), sig.size(), mu.data(),
3413-
mu.size(), nullptr, 0)) {
3426+
} else {
3427+
if (extmu.data()[0] == 0) {
3428+
// verify the signatures raw sign mode
3429+
if (mldsa_funcs.verify_internal(pk.data(), sig.data(), sig.size(), msg.data(),
3430+
msg.size(), nullptr, 0)) {
34143431
reply[0] = 1;
34153432
}
3416-
}
3417-
else if (nid == NID_MLDSA65) {
3418-
if (ml_dsa_extmu_65_verify_internal(pk.data(), sig.data(), sig.size(), mu.data(),
3419-
mu.size(), nullptr, 0)) {
3433+
} else {
3434+
// verify the signatures digest sign mode (externalmu)
3435+
if (mldsa_funcs.extmu_verify_internal(pk.data(), sig.data(), sig.size(), mu.data(),
3436+
mu.size(), nullptr, 0)) {
34203437
reply[0] = 1;
34213438
}
34223439
}
3423-
else if (nid == NID_MLDSA87) {
3424-
if (ml_dsa_extmu_87_verify_internal(pk.data(), sig.data(), sig.size(), mu.data(),
3425-
mu.size(), nullptr, 0)) {
3426-
reply[0] = 1;
3427-
}
3428-
}
34293440
}
3441+
34303442
return write_reply({Span<const uint8_t>(reply)});
34313443
}
34323444

@@ -3694,12 +3706,12 @@ static struct {
36943706
{"ML-DSA/ML-DSA-44/keyGen", 1, ML_DSA_KEYGEN<NID_MLDSA44>},
36953707
{"ML-DSA/ML-DSA-65/keyGen", 1, ML_DSA_KEYGEN<NID_MLDSA65>},
36963708
{"ML-DSA/ML-DSA-87/keyGen", 1, ML_DSA_KEYGEN<NID_MLDSA87>},
3697-
{"ML-DSA/ML-DSA-44/sigGen", 5, ML_DSA_SIGGEN<NID_MLDSA44>},
3698-
{"ML-DSA/ML-DSA-65/sigGen", 5, ML_DSA_SIGGEN<NID_MLDSA65>},
3699-
{"ML-DSA/ML-DSA-87/sigGen", 5, ML_DSA_SIGGEN<NID_MLDSA87>},
3700-
{"ML-DSA/ML-DSA-44/sigVer", 5, ML_DSA_SIGVER<NID_MLDSA44>},
3701-
{"ML-DSA/ML-DSA-65/sigVer", 5, ML_DSA_SIGVER<NID_MLDSA65>},
3702-
{"ML-DSA/ML-DSA-87/sigVer", 5, ML_DSA_SIGVER<NID_MLDSA87>}};
3709+
{"ML-DSA/ML-DSA-44/sigGen", 6, ML_DSA_SIGGEN<NID_MLDSA44>},
3710+
{"ML-DSA/ML-DSA-65/sigGen", 6, ML_DSA_SIGGEN<NID_MLDSA65>},
3711+
{"ML-DSA/ML-DSA-87/sigGen", 6, ML_DSA_SIGGEN<NID_MLDSA87>},
3712+
{"ML-DSA/ML-DSA-44/sigVer", 6, ML_DSA_SIGVER<NID_MLDSA44>},
3713+
{"ML-DSA/ML-DSA-65/sigVer", 6, ML_DSA_SIGVER<NID_MLDSA65>},
3714+
{"ML-DSA/ML-DSA-87/sigVer", 6, ML_DSA_SIGVER<NID_MLDSA87>}};
37033715

37043716
Handler FindHandler(Span<const Span<const uint8_t>> args) {
37053717
const bssl::Span<const uint8_t> algorithm = args[0];

0 commit comments

Comments
 (0)