Skip to content

Commit 01e7f64

Browse files
committed
PKCS7: fix signature verification for hybrids
Signed-off-by: Stephan Mueller <smueller@chronox.de>
1 parent 12b601c commit 01e7f64

File tree

5 files changed

+142
-11
lines changed

5 files changed

+142
-11
lines changed

apps/src/sbsign.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@
2020
* This implementation is intended to provide a drop-in replacement for the
2121
* sbsign tool from
2222
* http://git.kernel.org/pub/scm/linux/kernel/git/jejb/sbsigntools.git.
23+
*
24+
* The following differences exist though:
25+
*
26+
* - Unlike OpenSSL, leancrypto's certificate parsing only supports one
27+
* certificate per PEM file (OpenSSL supports multiple PEM-formatted
28+
* certificate blobs in one file). Thus, if you have multiple additional
29+
* certificates you want to provide with --addcert, have one DER or PEM
30+
* formatted certificate per file, but supply each file with a separate
31+
* --addcert option.
2332
*/
2433
#define _GNU_SOURCE
2534

apps/tests/meson.build

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,32 @@ if (host_machine.system() != 'windows' and
585585
],
586586
timeout: 300, suite: regression,
587587
should_fail: fips140_negative_expect_fail)
588+
589+
test('X.509/PKCS8 keygen/siggen/sigver ML-DSA87-ED448',
590+
siggen_test_script,
591+
args: [ 'ML-DSA87-ED448',
592+
lc_x509_generator.full_path(),
593+
lc_pkcs7_generator.full_path(),
594+
],
595+
timeout: 300, suite: regression,
596+
should_fail: fips140_negative_expect_fail)
597+
test('X.509/PKCS8 keygen/siggen/sigver ML-DSA65-ED25519',
598+
siggen_test_script,
599+
args: [ 'ML-DSA65-ED25519',
600+
lc_x509_generator.full_path(),
601+
lc_pkcs7_generator.full_path(),
602+
],
603+
timeout: 300, suite: regression,
604+
should_fail: fips140_negative_expect_fail)
605+
test('X.509/PKCS8 keygen/siggen/sigver ML-DSA44-ED25519',
606+
siggen_test_script,
607+
args: [ 'ML-DSA44-ED25519',
608+
lc_x509_generator.full_path(),
609+
lc_pkcs7_generator.full_path(),
610+
],
611+
timeout: 300, suite: regression,
612+
should_fail: fips140_negative_expect_fail)
613+
588614
test('X.509/PKCS8 keygen/siggen/sigver LC - OpenSSL Interop SLH-DSA-SHAKE-128F',
589615
siggen_test_script,
590616
args: [ 'SLH-DSA-SHAKE-128F',
@@ -663,6 +689,35 @@ if (host_machine.system() != 'windows' and
663689
],
664690
timeout: 300, suite: regression,
665691
should_fail: fips140_negative_expect_fail)
692+
693+
test('Secure boot sbsign tool ML-DSA87-ED448',
694+
sbsign_test_script,
695+
args: [ 'ML-DSA87-ED448',
696+
lc_x509_generator.full_path(),
697+
sbsign.full_path(),
698+
lc_pkcs7_generator.full_path(),
699+
],
700+
timeout: 300, suite: regression,
701+
should_fail: fips140_negative_expect_fail)
702+
test('Secure boot sbsign tool ML-DSA65-ED25519',
703+
sbsign_test_script,
704+
args: [ 'ML-DSA65-ED25519',
705+
lc_x509_generator.full_path(),
706+
sbsign.full_path(),
707+
lc_pkcs7_generator.full_path(),
708+
],
709+
timeout: 300, suite: regression,
710+
should_fail: fips140_negative_expect_fail)
711+
test('Secure boot sbsign tool ML-DSA44-ED25519',
712+
sbsign_test_script,
713+
args: [ 'ML-DSA44-ED25519',
714+
lc_x509_generator.full_path(),
715+
sbsign.full_path(),
716+
lc_pkcs7_generator.full_path(),
717+
],
718+
timeout: 300, suite: regression,
719+
should_fail: fips140_negative_expect_fail)
720+
666721
test('Secure boot sbsign tool SLH-DSA-SHAKE-128F',
667722
sbsign_test_script,
668723
args: [ 'SLH-DSA-SHAKE-128F',

apps/tests/sbsign_test.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
# the following steps:
77
#
88
# 1. compile leancrypto with sbign tool enabled
9-
# 2. update variable SBSIGN below to point to the sbsign tool
9+
# 2. update variables LC_X509_GENERATOR, SBSIGN, LC_PKCS7_GENERATOR below to
10+
# point to the respective applications
1011
# 3. Execute this script
1112
#
1213
# Expected result: no failures should be shown

asn1/src/asym_key_dilithium_ed25519.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lc_dilithium.h"
2323
#include "lc_hash.h"
2424
#include "lc_sphincs.h"
25+
#include "pkcs7_internal.h"
2526
#include "ret_checkers.h"
2627
#include "small_stack_support.h"
2728
#include "x509_algorithm_mapper.h"
@@ -274,6 +275,7 @@ int public_key_decode_dilithium_ed25519(
274275
static int
275276
public_key_dilithium_ed25519_get_data(const uint8_t **data_ptr,
276277
size_t *data_len,
278+
int *authattrs_tag,
277279
const struct lc_public_key_signature *sig)
278280
{
279281
/*
@@ -285,16 +287,45 @@ public_key_dilithium_ed25519_get_data(const uint8_t **data_ptr,
285287
if (sig->authattrs) {
286288
*data_ptr = sig->authattrs;
287289
*data_len = sig->authattrs_size;
290+
if (authattrs_tag)
291+
*authattrs_tag = 1;
288292
return 0;
289293
} else if (sig->raw_data) {
290294
*data_ptr = sig->raw_data;
291295
*data_len = sig->raw_data_len;
296+
if (authattrs_tag)
297+
*authattrs_tag = 0;
292298
return 0;
293299
} else {
294300
return -EOPNOTSUPP;
295301
}
296302
}
297303

304+
static int lc_xof_authattr(const struct lc_hash *xof, const uint8_t *in,
305+
size_t inlen, uint8_t *digest, size_t digestlen,
306+
int authattrs_tag)
307+
{
308+
LC_HASH_CTX_ON_STACK(hash_ctx, xof);
309+
int ret;
310+
311+
CKINT(lc_hash_init(hash_ctx));
312+
if (authattrs_tag) {
313+
lc_hash_update(hash_ctx, &lc_pkcs7_authattr_tag,
314+
sizeof(lc_pkcs7_authattr_tag));
315+
}
316+
lc_hash_update(hash_ctx, in, inlen);
317+
lc_hash_set_digestsize(hash_ctx, digestlen);
318+
if (lc_hash_digestsize(hash_ctx) != digestlen) {
319+
memset(digest, 0, digestlen);
320+
return 0;
321+
}
322+
lc_hash_final(hash_ctx, digest);
323+
324+
out:
325+
lc_hash_zero(hash_ctx);
326+
return ret;
327+
}
328+
298329
int public_key_verify_signature_dilithium_ed25519(
299330
const struct lc_public_key *pkey,
300331
const struct lc_public_key_signature *sig)
@@ -307,15 +338,16 @@ int public_key_verify_signature_dilithium_ed25519(
307338
const struct lc_hash *hash_algo;
308339
const uint8_t *dilithium_src, *ed25519_src, *randomizer, *data_ptr;
309340
size_t dilithium_src_len, ed25519_src_len, data_len;
310-
int ret;
341+
int ret, authattrs_tag;
311342
LC_DILITHIUM_ED25519_CTX_ON_STACK(ctx);
312343
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
313344

314345
/* A signature verification does not work with a private key */
315346
if (pkey->key_is_private)
316347
return -EKEYREJECTED;
317348

318-
CKINT(public_key_dilithium_ed25519_get_data(&data_ptr, &data_len, sig));
349+
CKINT(public_key_dilithium_ed25519_get_data(&data_ptr, &data_len,
350+
&authattrs_tag, sig));
319351

320352
if (sig->s_size <
321353
(LC_ED25519_SIGBYTES + LC_X509_SIGNATURE_RANDOMIZER_SIZE))
@@ -348,8 +380,8 @@ int public_key_verify_signature_dilithium_ed25519(
348380

349381
CKINT(lc_x509_sig_type_to_hash(sig->pkey_algo, &hash_algo));
350382
/* XOF works as digest size of 64 bytes is same as XOF size */
351-
CKINT(lc_xof(hash_algo, data_ptr, data_len, ws->ph_message,
352-
sizeof(ws->ph_message)));
383+
CKINT(lc_xof_authattr(hash_algo, data_ptr, data_len, ws->ph_message,
384+
sizeof(ws->ph_message), authattrs_tag));
353385

354386
/*
355387
* TODO currently no ctx is supported. This implies that ctx == NULL.
@@ -393,7 +425,8 @@ int public_key_generate_signature_dilithium_ed25519(
393425
LC_DILITHIUM_ED25519_CTX_ON_STACK(ctx);
394426
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
395427

396-
CKINT(public_key_dilithium_ed25519_get_data(&data_ptr, &data_len, sig));
428+
CKINT(public_key_dilithium_ed25519_get_data(&data_ptr, &data_len, NULL,
429+
sig));
397430

398431
/* Generate the randomizer value */
399432
CKINT(lc_rng_generate(lc_seeded_rng, (uint8_t *)"X509.Comp.Sig.25519",

asn1/src/asym_key_dilithium_ed448.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lc_dilithium.h"
2323
#include "lc_hash.h"
2424
#include "lc_sphincs.h"
25+
#include "pkcs7_internal.h"
2526
#include "ret_checkers.h"
2627
#include "small_stack_support.h"
2728
#include "x509_algorithm_mapper.h"
@@ -284,6 +285,7 @@ int public_key_decode_dilithium_ed448(
284285

285286
static int
286287
public_key_dilithium_ed448_get_data(const uint8_t **data_ptr, size_t *data_len,
288+
int *authattrs_tag,
287289
const struct lc_public_key_signature *sig)
288290
{
289291
/*
@@ -295,16 +297,45 @@ public_key_dilithium_ed448_get_data(const uint8_t **data_ptr, size_t *data_len,
295297
if (sig->authattrs) {
296298
*data_ptr = sig->authattrs;
297299
*data_len = sig->authattrs_size;
300+
if (authattrs_tag)
301+
*authattrs_tag = 1;
298302
return 0;
299303
} else if (sig->raw_data) {
300304
*data_ptr = sig->raw_data;
301305
*data_len = sig->raw_data_len;
306+
if (authattrs_tag)
307+
*authattrs_tag = 0;
302308
return 0;
303309
} else {
304310
return -EOPNOTSUPP;
305311
}
306312
}
307313

314+
static int lc_xof_authattr(const struct lc_hash *xof, const uint8_t *in,
315+
size_t inlen, uint8_t *digest, size_t digestlen,
316+
int authattrs_tag)
317+
{
318+
LC_HASH_CTX_ON_STACK(hash_ctx, xof);
319+
int ret;
320+
321+
CKINT(lc_hash_init(hash_ctx));
322+
if (authattrs_tag) {
323+
lc_hash_update(hash_ctx, &lc_pkcs7_authattr_tag,
324+
sizeof(lc_pkcs7_authattr_tag));
325+
}
326+
lc_hash_update(hash_ctx, in, inlen);
327+
lc_hash_set_digestsize(hash_ctx, digestlen);
328+
if (lc_hash_digestsize(hash_ctx) != digestlen) {
329+
memset(digest, 0, digestlen);
330+
return 0;
331+
}
332+
lc_hash_final(hash_ctx, digest);
333+
334+
out:
335+
lc_hash_zero(hash_ctx);
336+
return ret;
337+
}
338+
308339
int public_key_verify_signature_dilithium_ed448(
309340
const struct lc_public_key *pkey,
310341
const struct lc_public_key_signature *sig)
@@ -317,15 +348,16 @@ int public_key_verify_signature_dilithium_ed448(
317348
const struct lc_hash *hash_algo;
318349
const uint8_t *dilithium_src, *ed448_src, *randomizer, *data_ptr;
319350
size_t dilithium_src_len, ed448_src_len, data_len;
320-
int ret;
351+
int ret, authattrs_tag;
321352
LC_DILITHIUM_ED448_CTX_ON_STACK(ctx);
322353
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
323354

324355
/* A signature verification does not work with a private key */
325356
if (pkey->key_is_private)
326357
return -EKEYREJECTED;
327358

328-
CKINT(public_key_dilithium_ed448_get_data(&data_ptr, &data_len, sig));
359+
CKINT(public_key_dilithium_ed448_get_data(&data_ptr, &data_len,
360+
&authattrs_tag, sig));
329361

330362
if (sig->s_size <
331363
(LC_ED448_SIGBYTES + LC_X509_SIGNATURE_RANDOMIZER_SIZE))
@@ -358,8 +390,8 @@ int public_key_verify_signature_dilithium_ed448(
358390

359391
CKINT(lc_x509_sig_type_to_hash(sig->pkey_algo, &hash_algo));
360392
/* XOF works as digest size of 64 bytes is same as XOF size */
361-
CKINT(lc_xof(hash_algo, data_ptr, data_len, ws->ph_message,
362-
sizeof(ws->ph_message)));
393+
CKINT(lc_xof_authattr(hash_algo, data_ptr, data_len, ws->ph_message,
394+
sizeof(ws->ph_message), authattrs_tag));
363395

364396
/*
365397
* TODO currently no ctx is supported. This implies that ctx == NULL.
@@ -403,7 +435,8 @@ int public_key_generate_signature_dilithium_ed448(
403435
LC_DILITHIUM_ED448_CTX_ON_STACK(ctx);
404436
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
405437

406-
CKINT(public_key_dilithium_ed448_get_data(&data_ptr, &data_len, sig));
438+
CKINT(public_key_dilithium_ed448_get_data(&data_ptr, &data_len, NULL,
439+
sig));
407440

408441
/* Generate the randomizer value */
409442
CKINT(lc_rng_generate(lc_seeded_rng, (uint8_t *)"X509.Comp.Sig.448", 17,

0 commit comments

Comments
 (0)