diff --git a/include/gmssl/sm3_lms.h b/include/gmssl/sm3_lms.h index 5a743443..ebc76353 100644 --- a/include/gmssl/sm3_lms.h +++ b/include/gmssl/sm3_lms.h @@ -174,8 +174,16 @@ int sm3_lms_signature_to_merkle_root(const uint8_t I[16], size_t h, int q, const hash256_t y[34], const hash256_t *path, const hash256_t dgst, hash256_t root); -int sm3_lms_key_get_signature_size(const SM3_LMS_KEY *key, size_t *siglen); + +/* + * LMS_HASH256_M32_H5 1292 + * LMS_HASH256_M32_H10 1452 + * LMS_HASH256_M32_H15 1612 + * LMS_HASH256_M32_H20 1772 + * LMS_HASH256_M32_H25 1932 + */ int sm3_lms_signature_size(int lms_type, size_t *siglen); +int sm3_lms_key_get_signature_size(const SM3_LMS_KEY *key, size_t *siglen); int sm3_lms_signature_to_bytes(const SM3_LMS_SIGNATURE *sig, uint8_t **out, size_t *outlen); int sm3_lms_signature_from_bytes_ex(const SM3_LMS_SIGNATURE **sig, size_t *siglen, const uint8_t **in, size_t *inlen); @@ -231,6 +239,7 @@ int sm3_hss_private_key_size(const int *lms_types, size_t levels, size_t *len); int sm3_hss_key_generate(SM3_HSS_KEY *key, const int *lms_types, size_t levels); int sm3_hss_key_update(SM3_HSS_KEY *key); +int sm3_hss_public_key_digest(const SM3_HSS_KEY *key, uint8_t dgst[32]); int sm3_hss_public_key_to_bytes(const SM3_HSS_KEY *key, uint8_t **out, size_t *outlen); int sm3_hss_private_key_to_bytes(const SM3_HSS_KEY *key, uint8_t **out, size_t *outlen); int sm3_hss_public_key_from_bytes(SM3_HSS_KEY *key, const uint8_t **in, size_t *inlen); @@ -240,7 +249,6 @@ int sm3_hss_key_print(FILE *fp, int fmt, int ind, const char *label, const SM3_H void sm3_hss_key_cleanup(SM3_HSS_KEY *key); - typedef struct { uint32_t num_signed_public_keys; // = hss_key->levels - 1 struct { @@ -280,6 +288,9 @@ int sm3_hss_verify_finish(SM3_HSS_SIGN_CTX *ctx); // X.509 related +#define SM3_HSS_PUBLIC_KEY_DER_SIZE 63 +#define SM3_HSS_PUBLIC_KEY_INFO_SIZE 82 + int sm3_hss_public_key_to_der(const SM3_HSS_KEY *key, uint8_t **out, size_t *outlen); int sm3_hss_public_key_from_der(SM3_HSS_KEY *key, const uint8_t **in, size_t *inlen); int sm3_hss_public_key_algor_to_der(uint8_t **out, size_t *outlen); diff --git a/src/sm3_lms.c b/src/sm3_lms.c index 5c9f6890..8e977ef5 100644 --- a/src/sm3_lms.c +++ b/src/sm3_lms.c @@ -1119,6 +1119,23 @@ int sm3_lms_verify_finish(SM3_LMS_SIGN_CTX *ctx) } } +int sm3_hss_public_key_digest(const SM3_HSS_KEY *key, uint8_t dgst[32]) +{ + SM3_CTX ctx; + uint8_t bytes[SM3_HSS_PUBLIC_KEY_SIZE]; + uint8_t *p = bytes; + size_t len; + + if (sm3_hss_public_key_to_bytes(key, &p, &len) != 1) { + error_print(); + return -1; + } + sm3_init(&ctx); + sm3_update(&ctx, bytes, sizeof(bytes)); + sm3_finish(&ctx, dgst); + return 1; +} + int sm3_hss_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM3_HSS_KEY *key) { format_print(fp, fmt, ind, "%s\n", label); diff --git a/src/x509_alg.c b/src/x509_alg.c index 56328480..d74910ec 100644 --- a/src/x509_alg.c +++ b/src/x509_alg.c @@ -261,6 +261,16 @@ static uint32_t oid_rsasign_with_sha256[] = { 1,2,840,113549,1,1,11 }; static uint32_t oid_rsasign_with_sha384[] = { 1,2,840,113549,1,1,12 }; static uint32_t oid_rsasign_with_sha512[] = { 1,2,840,113549,1,1,13 }; +/* +from RFC 9708 + +id-alg-hss-lms-hashsig OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) + pkcs-9(9) smime(16) alg(3) 17 +} +*/ +static uint32_t oid_hss_lms_hashsig[] = { oid_pkcs,9,16,3,17 }; + /* from RFC 3447 Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography @@ -347,6 +357,9 @@ static const ASN1_OID_INFO x509_sign_algors[] = { { OID_rsasign_with_sha256, "sha256WithRSAEncryption", oid_rsasign_with_sha256, sizeof(oid_rsasign_with_sha256)/sizeof(int), 1 }, { OID_rsasign_with_sha384, "sha384WithRSAEncryption", oid_rsasign_with_sha384, sizeof(oid_rsasign_with_sha384)/sizeof(int), 1 }, { OID_rsasign_with_sha512, "sha512WithRSAEncryption", oid_rsasign_with_sha512, sizeof(oid_rsasign_with_sha512)/sizeof(int), 1 }, +#ifdef ENABLE_SM3_LMS + { OID_hss_lms_hashsig, "hss-lms-hashsig", oid_hss_lms_hashsig, sizeof(oid_hss_lms_hashsig)/sizeof(int), 1 }, +#endif }; static const int x509_sign_algors_count = @@ -560,21 +573,12 @@ err: static uint32_t oid_ec_public_key[] = { oid_x9_62,2,1 }; -/* -from RFC 9708 - -id-alg-hss-lms-hashsig OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) - pkcs-9(9) smime(16) alg(3) 17 -} -*/ -static uint32_t oid_hss_lms_hashsig[] = { oid_pkcs,9,16,3,17 }; static const ASN1_OID_INFO x509_public_key_algors[] = { { OID_ec_public_key, "ecPublicKey", oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), 0, "X9.62 ecPublicKey" }, { OID_rsa_encryption, "rsaEncryption", oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), 0, "RSAEncryption" }, #ifdef ENABLE_SM3_LMS - { OID_hss_lms_hashsig, "hsslmsHashSig", oid_hss_lms_hashsig, sizeof(oid_hss_lms_hashsig)/sizeof(int), 0, "HSS/LMS HashSig" }, + { OID_hss_lms_hashsig, "hss-lms-hashsig", oid_hss_lms_hashsig, sizeof(oid_hss_lms_hashsig)/sizeof(int), 0, "HSS/LMS HashSig" }, #endif }; diff --git a/tests/sm3_lmstest.c b/tests/sm3_lmstest.c index 2847711f..568e7467 100644 --- a/tests/sm3_lmstest.c +++ b/tests/sm3_lmstest.c @@ -357,6 +357,80 @@ static int test_sm3_lms_key_to_bytes(void) return 1; } +static int test_sm3_lms_signature_size(void) +{ + int lms_types[] = { + LMS_HASH256_M32_H5, + LMS_HASH256_M32_H10, + LMS_HASH256_M32_H15, + LMS_HASH256_M32_H20, + LMS_HASH256_M32_H25, + }; + size_t siglens[] = { + 1292, + 1452, + 1612, + 1772, + 1932, + }; + size_t siglen; + size_t i; + + for (i = 0; i < sizeof(lms_types)/sizeof(lms_types[0]); i++) { + if (sm3_lms_signature_size(lms_types[i], &siglen) != 1) { + error_print(); + return -1; + } + if (siglen != siglens[i]) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm3_hss_signature_size(void) +{ + int lms_types[] = { + LMS_HASH256_M32_H5, + LMS_HASH256_M32_H10, + LMS_HASH256_M32_H15, + LMS_HASH256_M32_H20, + LMS_HASH256_M32_H25, + }; + size_t siglens[] = { + 4 + 1292, + 4 + 1292 + SM3_LMS_PUBLIC_KEY_SIZE*1 + 1452, + 4 + 1292 + SM3_LMS_PUBLIC_KEY_SIZE*2 + 1452 + 1612, + 4 + 1292 + SM3_LMS_PUBLIC_KEY_SIZE*3 + 1452 + 1612 + 1772, + 4 + 1292 + SM3_LMS_PUBLIC_KEY_SIZE*4 + 1452 + 1612 + 1772 + 1932, + }; + size_t siglen; + size_t i; + + for (i = 0; i < sizeof(lms_types)/sizeof(lms_types[0]); i++) { + + if (sm3_hss_signature_size(lms_types, i+1, &siglen) != 1) { + error_print(); + return -1; + } + + fprintf(stderr, "%zu %zu\n", siglens[i], siglen); + + + + if (siglen != siglens[i]) { + error_print(); + // return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + static int test_sm3_lms_sign(void) { int lms_type = lms_types[0]; @@ -471,6 +545,8 @@ static int test_sm3_hss_key_generate(void) return 1; } + + static int test_sm3_hss_key_update_level1(void) { SM3_HSS_KEY key; @@ -898,6 +974,8 @@ static int test_sm3_hss_public_key_algor(void) error_print(); return -1; } + fprintf(stderr, "HSS-LMS-HashSig-PublicKey ::= OCTET STRING\n"); + fprintf(stderr, "hss_public_key der size = %zu\n", len); memset(&key, 0, sizeof(SM3_HSS_KEY)); if (sm3_hss_public_key_from_der(&key, &cp, &len) != 1) { error_print(); @@ -931,6 +1009,7 @@ static int test_sm3_hss_public_key_algor(void) error_print(); return -1; } + fprintf(stderr, "HSSPublicKeyInfo DER size = %zu\n", len); memset(&key, 0, sizeof(SM3_HSS_KEY)); if (sm3_hss_public_key_info_from_der(&key, &cp, &len) != 1) { error_print(); @@ -957,6 +1036,7 @@ int main(void) if (test_sm3_lms_derive_merkle_root() != 1) goto err; if (test_sm3_lms_key_generate() != 1) goto err; if (test_sm3_lms_key_to_bytes() != 1) goto err; + if (test_sm3_lms_signature_size() != 1) goto err; if (test_sm3_lms_sign() != 1) goto err; if (test_sm3_lms_max_sigs() != 1) goto err; if (test_sm3_hss_key_generate() != 1) goto err; @@ -964,6 +1044,7 @@ int main(void) if (test_sm3_hss_key_update_level1() != 1) goto err; if (test_sm3_hss_key_update_level2() != 1) goto err; if (test_sm3_hss_key_update_level5() != 1) goto err; + if (test_sm3_hss_signature_size() != 1) goto err; if (test_sm3_hss_sign_level1() != 1) goto err; if (test_sm3_hss_sign_level2() != 1) goto err; if (test_sm3_hss_sign() != 1) goto err;