mirror of
https://github.com/openssl/openssl.git
synced 2025-04-06 20:20:50 +08:00
Add base code to load a SLH_DSA public key.
This loads a SLH_DSA public key from data. A simple SLH_DSA keymanager imports this key. Initially this only has a parameter set for SLH-DSA-SHA2-128s Reviewed-by: Paul Dale <ppzgs1@gmail.com> Reviewed-by: Viktor Dukhovni <viktor@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org> (Merged from https://github.com/openssl/openssl/pull/25882)
This commit is contained in:
parent
16395ee9cc
commit
34f4cacc8f
@ -6,7 +6,7 @@ SUBDIRS=objects buffer bio stack lhash hashtable rand evp asn1 pem x509 conf \
|
||||
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
|
||||
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
|
||||
err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \
|
||||
ffc hpke thread ml_dsa
|
||||
ffc hpke thread ml_dsa slh_dsa
|
||||
|
||||
LIBS=../libcrypto
|
||||
|
||||
|
7
crypto/slh_dsa/build.info
Normal file
7
crypto/slh_dsa/build.info
Normal file
@ -0,0 +1,7 @@
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=slh_dsa_key.c slh_params.c
|
||||
|
||||
IF[{- !$disabled{'slh_dsa'} -}]
|
||||
SOURCE[../../libcrypto]=$COMMON
|
||||
ENDIF
|
142
crypto/slh_dsa/slh_dsa_key.c
Normal file
142
crypto/slh_dsa/slh_dsa_key.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "slh_dsa_local.h"
|
||||
#include "slh_dsa_key.h"
|
||||
|
||||
/**
|
||||
* @brief Create a new SLH_DSA_KEY object
|
||||
*
|
||||
* @param libctx A OSSL_LIB_CTX object used for fetching algorithms.
|
||||
* @param alg The algrithm name associated with the key type
|
||||
* @returns The new SLH_DSA_KEY object on success, or NULL on malloc failure
|
||||
*/
|
||||
SLH_DSA_KEY *ossl_slh_dsa_key_new(OSSL_LIB_CTX *libctx, const char *alg)
|
||||
{
|
||||
SLH_DSA_KEY *ret;
|
||||
const SLH_DSA_PARAMS *params = ossl_slh_dsa_params_get(alg);
|
||||
|
||||
if (params == NULL)
|
||||
return NULL;
|
||||
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret != NULL) {
|
||||
if (!CRYPTO_NEW_REF(&ret->references, 1)) {
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
ret->libctx = libctx;
|
||||
ret->params = params;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy a SLH_DSA_KEY object
|
||||
*/
|
||||
void ossl_slh_dsa_key_free(SLH_DSA_KEY *key)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (key == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&key->references, &i);
|
||||
REF_PRINT_COUNT("SLH_DSA_KEY", key);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
OPENSSL_free(key->propq);
|
||||
CRYPTO_FREE_REF(&key->references);
|
||||
OPENSSL_free(key);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Increase the reference count for a SLH_DSA_KEY object.
|
||||
* @returns 1 on success or 0 otherwise.
|
||||
*/
|
||||
int ossl_slh_dsa_key_up_ref(SLH_DSA_KEY *key)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (CRYPTO_UP_REF(&key->references, &i) <= 0)
|
||||
return 0;
|
||||
|
||||
REF_PRINT_COUNT("SLH_DSA_KEY", key);
|
||||
REF_ASSERT_ISNT(i < 2);
|
||||
return ((i > 1) ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Are 2 keys equal?
|
||||
*
|
||||
* To be equal the keys must have the same key data.
|
||||
*
|
||||
* @param key1 A SLH_DSA_KEY object
|
||||
* @param key2 A SLH_DSA_KEY object
|
||||
* @param selection to select public and/or private component comparison.
|
||||
* @returns 1 if the keys are equal otherwise it returns 0.
|
||||
*/
|
||||
int ossl_slh_dsa_key_equal(const SLH_DSA_KEY *key1, const SLH_DSA_KEY *key2,
|
||||
int selection)
|
||||
{
|
||||
int ok = 1;
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
|
||||
if (key1->key_len != key2->key_len)
|
||||
return 0;
|
||||
ok = (memcmp(key1->pub, key2->pub, key1->key_len) == 0);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ossl_slh_dsa_key_has(const SLH_DSA_KEY *key, int selection)
|
||||
{
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
|
||||
if (key->key_len == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM params[])
|
||||
{
|
||||
size_t n, key_len, len = 0;
|
||||
const OSSL_PARAM *param_pub;
|
||||
void *p;
|
||||
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
n = key->params->n;
|
||||
assert(n != 0);
|
||||
/* Both the public and private key are composed of 2 elements of size n */
|
||||
key_len = 2 * n;
|
||||
|
||||
param_pub = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
if (param_pub == NULL)
|
||||
goto err;
|
||||
p = key->pub;
|
||||
if (!OSSL_PARAM_get_octet_string(param_pub, &p, key_len, &len))
|
||||
goto err;
|
||||
if (len != key_len)
|
||||
goto err;
|
||||
key->key_len = key_len; /* This indicates the public key is present */
|
||||
return 1;
|
||||
err:
|
||||
key->key_len = 0;
|
||||
return 0;
|
||||
}
|
22
crypto/slh_dsa/slh_dsa_key.h
Normal file
22
crypto/slh_dsa/slh_dsa_key.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/e_os2.h>
|
||||
#include "internal/refcount.h"
|
||||
|
||||
#define SLH_DSA_MAX_KEYLEN 32 * 2 /* 2 * n */
|
||||
|
||||
struct slh_dsa_key_st {
|
||||
uint8_t pub[SLH_DSA_MAX_KEYLEN];
|
||||
size_t key_len; /* This value is set to 2 * n if there is a public key */
|
||||
CRYPTO_REF_COUNT references;
|
||||
OSSL_LIB_CTX *libctx;
|
||||
char *propq;
|
||||
const SLH_DSA_PARAMS *params;
|
||||
};
|
11
crypto/slh_dsa/slh_dsa_local.h
Normal file
11
crypto/slh_dsa/slh_dsa_local.h
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "crypto/slh_dsa.h"
|
||||
#include "slh_params.h"
|
36
crypto/slh_dsa/slh_params.c
Normal file
36
crypto/slh_dsa/slh_params.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "slh_params.h"
|
||||
|
||||
/*
|
||||
* See FIPS 205 Section 11 Table 2
|
||||
* n h d hm a k m sc pk sig
|
||||
*/
|
||||
#define OSSL_SLH_DSA_128S 16, 63, 7, 9, 12, 14, 30, 1, 32, 7856
|
||||
|
||||
static const SLH_DSA_PARAMS slh_dsa_params[] = {
|
||||
{"SLH-DSA-SHA2-128s", 0, OSSL_SLH_DSA_128S},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A getter to convert an algorithm name into a SLH_DSA_PARAMS object
|
||||
*/
|
||||
const SLH_DSA_PARAMS *ossl_slh_dsa_params_get(const char *alg)
|
||||
{
|
||||
const SLH_DSA_PARAMS *p;
|
||||
|
||||
for (p = slh_dsa_params; p->alg != NULL; ++p) {
|
||||
if (strcmp(p->alg, alg) == 0)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
31
crypto/slh_dsa/slh_params.h
Normal file
31
crypto/slh_dsa/slh_params.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/e_os2.h>
|
||||
|
||||
/*
|
||||
* Refer to FIPS 205 Section 11 parameter sets.
|
||||
* lgw has been omitted since it is 4 for all algorithms i.e log(16)
|
||||
*/
|
||||
typedef struct slh_dsa_params_st {
|
||||
const char *alg;
|
||||
int is_shake;
|
||||
uint32_t n; /* Security parameter (Hash output size in bytes) (16, 24, 32) */
|
||||
uint32_t h; /* The total height of the tree (63, 64, 66, 68). #keypairs = 2^h */
|
||||
uint32_t d; /* The number of tree layers (7, 8, 17, 22) */
|
||||
uint32_t hm; /* The height (h') of each merkle tree. (h = hm * d ) */
|
||||
uint32_t a; /* Height of a FORS tree */
|
||||
uint32_t k; /* The number of FORS trees */
|
||||
uint32_t m; /* The size of H_MSG() output */
|
||||
uint32_t security_category;
|
||||
uint32_t pk_len;
|
||||
uint32_t sig_len;
|
||||
} SLH_DSA_PARAMS;
|
||||
|
||||
const SLH_DSA_PARAMS *ossl_slh_dsa_params_get(const char *alg);
|
28
include/crypto/slh_dsa.h
Normal file
28
include/crypto/slh_dsa.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* Internal SLH_DSA functions for other submodules, not for application use */
|
||||
|
||||
#ifndef OSSL_CRYPTO_SLH_DSA_H
|
||||
# define OSSL_CRYPTO_SLH_DSA_H
|
||||
|
||||
# pragma once
|
||||
# include <openssl/e_os2.h>
|
||||
# include <openssl/types.h>
|
||||
# include "crypto/types.h"
|
||||
|
||||
SLH_DSA_KEY *ossl_slh_dsa_key_new(OSSL_LIB_CTX *libctx, const char *alg);
|
||||
void ossl_slh_dsa_key_free(SLH_DSA_KEY *key);
|
||||
int ossl_slh_dsa_key_up_ref(SLH_DSA_KEY *key);
|
||||
int ossl_slh_dsa_key_equal(const SLH_DSA_KEY *key1, const SLH_DSA_KEY *key2,
|
||||
int selection);
|
||||
int ossl_slh_dsa_key_has(const SLH_DSA_KEY *key, int selection);
|
||||
int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM *params);
|
||||
|
||||
#endif /* OSSL_CRYPTO_SLH_DSA_H */
|
@ -28,6 +28,9 @@ typedef struct dsa_st DSA;
|
||||
# ifndef OPENSSL_NO_EC
|
||||
typedef struct ecx_key_st ECX_KEY;
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_SLH_DSA
|
||||
typedef struct slh_dsa_key_st SLH_DSA_KEY;
|
||||
# endif
|
||||
|
||||
typedef struct prov_skey_st PROV_SKEY;
|
||||
|
||||
|
@ -577,6 +577,10 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = {
|
||||
PROV_DESCS_SecP384r1MLKEM1024 },
|
||||
# endif
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SLH_DSA
|
||||
{ PROV_NAMES_SLH_DSA_SHA2_128S, "provider=default", ossl_slh_dsa_sha2_128s_keymgmt_functions,
|
||||
PROV_DESCS_SLH_DSA_SHA2_128S },
|
||||
#endif /* OPENSSL_NO_SLH_DSA */
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -339,6 +339,9 @@ extern const OSSL_DISPATCH ossl_mlx_p256_kem_kmgmt_functions[];
|
||||
extern const OSSL_DISPATCH ossl_mlx_p384_kem_kmgmt_functions[];
|
||||
# endif
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SLH_DSA
|
||||
extern const OSSL_DISPATCH ossl_slh_dsa_sha2_128s_keymgmt_functions[];
|
||||
#endif /* OPENSSL_NO_SLH_DSA */
|
||||
|
||||
/* Key Exchange */
|
||||
extern const OSSL_DISPATCH ossl_dh_keyexch_functions[];
|
||||
|
@ -409,3 +409,5 @@
|
||||
#define PROV_DESCS_SecP256r1MLKEM768 "P-256+ML-KEM-768 TLS hybrid implementation"
|
||||
#define PROV_NAMES_SecP384r1MLKEM1024 "SecP384r1MLKEM1024"
|
||||
#define PROV_DESCS_SecP384r1MLKEM1024 "P-384+ML-KEM-1024 TLS hybrid implementation"
|
||||
#define PROV_NAMES_SLH_DSA_SHA2_128S "SLH-DSA-SHA2-128s:2.16.840.1.101.3.4.3.20"
|
||||
#define PROV_DESCS_SLH_DSA_SHA2_128S "OpenSSL SLH-DSA-SHA2-128s implementation"
|
||||
|
@ -12,6 +12,7 @@ $TEMPLATE_GOAL=../../libtemplate.a
|
||||
$ML_DSA_GOAL=../../libdefault.a ../../libfips.a
|
||||
$ML_KEM_GOAL=../../libdefault.a ../../libfips.a
|
||||
$TLS_ML_KEM_HYBRID_GOAL=../../libdefault.a ../../libfips.a
|
||||
$SLH_DSA_GOAL=../../libdefault.a
|
||||
|
||||
IF[{- !$disabled{dh} -}]
|
||||
SOURCE[$DH_GOAL]=dh_kmgmt.c
|
||||
@ -58,3 +59,7 @@ SOURCE[$TEMPLATE_GOAL]=template_kmgmt.c
|
||||
IF[{- !$disabled{'ml-dsa'} -}]
|
||||
SOURCE[$ML_DSA_GOAL]=ml_dsa_kmgmt.c
|
||||
ENDIF
|
||||
|
||||
IF[{- !$disabled{'slh-dsa'} -}]
|
||||
SOURCE[$SLH_DSA_GOAL]=slh_dsa_kmgmt.c
|
||||
ENDIF
|
||||
|
105
providers/implementations/keymgmt/slh_dsa_kmgmt.c
Normal file
105
providers/implementations/keymgmt/slh_dsa_kmgmt.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/param_build.h>
|
||||
#include "crypto/slh_dsa.h"
|
||||
#include "internal/param_build_set.h"
|
||||
#include "prov/implementations.h"
|
||||
#include "prov/providercommon.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
|
||||
static OSSL_FUNC_keymgmt_free_fn slh_dsa_free_key;
|
||||
static OSSL_FUNC_keymgmt_has_fn slh_dsa_has;
|
||||
static OSSL_FUNC_keymgmt_match_fn slh_dsa_match;
|
||||
static OSSL_FUNC_keymgmt_import_fn slh_dsa_import;
|
||||
static OSSL_FUNC_keymgmt_import_types_fn slh_dsa_imexport_types;
|
||||
|
||||
#define SLH_DSA_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_PUBLIC_KEY)
|
||||
|
||||
static void *slh_dsa_new_key(void *provctx, const char *alg)
|
||||
{
|
||||
if (!ossl_prov_is_running())
|
||||
return 0;
|
||||
|
||||
return ossl_slh_dsa_key_new(PROV_LIBCTX_OF(provctx), alg);
|
||||
}
|
||||
|
||||
static void slh_dsa_free_key(void *keydata)
|
||||
{
|
||||
ossl_slh_dsa_key_free((SLH_DSA_KEY *)keydata);
|
||||
}
|
||||
|
||||
static int slh_dsa_has(const void *keydata, int selection)
|
||||
{
|
||||
const SLH_DSA_KEY *key = keydata;
|
||||
|
||||
if (!ossl_prov_is_running() || key == NULL)
|
||||
return 0;
|
||||
if ((selection & SLH_DSA_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* the selection is not missing */
|
||||
|
||||
return ossl_slh_dsa_key_has(key, selection);
|
||||
}
|
||||
|
||||
static int slh_dsa_match(const void *keydata1, const void *keydata2, int selection)
|
||||
{
|
||||
const SLH_DSA_KEY *key1 = keydata1;
|
||||
const SLH_DSA_KEY *key2 = keydata2;
|
||||
|
||||
if (!ossl_prov_is_running())
|
||||
return 0;
|
||||
if (key1 == NULL || key2 == NULL)
|
||||
return 0;
|
||||
return ossl_slh_dsa_key_equal(key1, key2, selection);
|
||||
}
|
||||
|
||||
static int slh_dsa_import(void *keydata, int selection, const OSSL_PARAM params[])
|
||||
{
|
||||
SLH_DSA_KEY *key = keydata;
|
||||
|
||||
if (!ossl_prov_is_running() || key == NULL)
|
||||
return 0;
|
||||
|
||||
if ((selection & SLH_DSA_POSSIBLE_SELECTIONS) == 0)
|
||||
return 0;
|
||||
|
||||
return ossl_slh_dsa_key_fromdata(key, params);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM slh_dsa_key_types[] = {
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
static const OSSL_PARAM *slh_dsa_imexport_types(int selection)
|
||||
{
|
||||
if ((selection & SLH_DSA_POSSIBLE_SELECTIONS) == 0)
|
||||
return NULL;
|
||||
return slh_dsa_key_types;
|
||||
}
|
||||
|
||||
#define MAKE_KEYMGMT_FUNCTIONS(alg, fn) \
|
||||
static OSSL_FUNC_keymgmt_new_fn slh_dsa_##fn##_new_key; \
|
||||
static void *slh_dsa_##fn##_new_key(void *provctx) \
|
||||
{ \
|
||||
return slh_dsa_new_key(provctx, alg); \
|
||||
} \
|
||||
const OSSL_DISPATCH ossl_slh_dsa_##fn##_keymgmt_functions[] = { \
|
||||
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))slh_dsa_##fn##_new_key }, \
|
||||
{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))slh_dsa_free_key }, \
|
||||
{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))slh_dsa_has }, \
|
||||
{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))slh_dsa_match }, \
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))slh_dsa_import }, \
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))slh_dsa_imexport_types },\
|
||||
OSSL_DISPATCH_END \
|
||||
}
|
||||
|
||||
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHA2-128s", sha2_128s);
|
@ -273,6 +273,13 @@ IF[{- !$disabled{tests} -}]
|
||||
INCLUDE[evp_pkey_dhkem_test]=../include ../apps/include
|
||||
DEPEND[evp_pkey_dhkem_test]=../libcrypto.a libtestutil.a
|
||||
|
||||
IF[{- !$disabled{'slh-dsa'} -}]
|
||||
PROGRAMS{noinst}=slh_dsa_test
|
||||
SOURCE[slh_dsa_test]=slh_dsa_test.c
|
||||
INCLUDE[slh_dsa_test]=../include ../apps/include
|
||||
DEPEND[slh_dsa_test]=../libcrypto.a libtestutil.a
|
||||
ENDIF
|
||||
|
||||
IF[{- !$disabled{'deprecated-3.0'} -}]
|
||||
PROGRAMS{noinst}=igetest bftest casttest
|
||||
|
||||
|
25
test/recipes/30-test_slh_dsa.t
Normal file
25
test/recipes/30-test_slh_dsa.t
Normal file
@ -0,0 +1,25 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use OpenSSL::Test qw(:DEFAULT srctop_dir bldtop_dir);
|
||||
use OpenSSL::Test::Utils;
|
||||
|
||||
BEGIN {
|
||||
setup("test_slh_dsa");
|
||||
}
|
||||
|
||||
use lib srctop_dir('Configurations');
|
||||
use lib bldtop_dir('.');
|
||||
|
||||
plan skip_all => 'SLH-DSA is not supported in this build' if disabled('slh-dsa');
|
||||
plan tests => 1;
|
||||
|
||||
ok(run(test(["slh_dsa_test"])), "running slh_dsa_test");
|
57
test/slh_dsa.inc
Normal file
57
test/slh_dsa.inc
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
typedef struct SLH_DSA_ACVP_TEST_DATA_st {
|
||||
const char *alg;
|
||||
const unsigned char *pub;
|
||||
size_t pub_len;
|
||||
const unsigned char *priv;
|
||||
size_t priv_len;
|
||||
const unsigned char *msg;
|
||||
size_t msg_len;
|
||||
/* sha256 digest of the signature - this reduces the footprint this file */
|
||||
const unsigned char *sig_digest;
|
||||
size_t sig_digest_len;
|
||||
} SLH_DSA_ACVP_TEST_DATA;
|
||||
|
||||
#define SLH_DSA_ACVP_ITEM(name, alg) { \
|
||||
alg, \
|
||||
name##_pub, sizeof(name##_pub), \
|
||||
name##_priv, sizeof(name##_priv), \
|
||||
name##_msg, sizeof(name##_msg), \
|
||||
name##_sig_digest, sizeof(name##_sig_digest) }
|
||||
|
||||
/*
|
||||
* Test vectors from
|
||||
* usnistgov/ACVP-Server/refs/heads/master/gen-val/json-files/SLH-DSA-sigGen-FIPS205/internalProjection.json
|
||||
*
|
||||
* Note that the test vectors store the private & public components in one field
|
||||
* (e.g sk)
|
||||
* The following data separates these fields.
|
||||
*/
|
||||
static const uint8_t slh_dsa_sha2_128s_0_priv[] = {
|
||||
0x62, 0xb1, 0x97, 0x3a, 0x4d, 0xe0, 0x96, 0x3d, 0x74, 0xc1, 0xcb, 0x30, 0xfc, 0x8f, 0x56, 0x75,
|
||||
0xcf, 0xc8, 0x48, 0x80, 0xe4, 0xf0, 0xe1, 0xb4, 0x46, 0xb4, 0xf5, 0xd1, 0x3b, 0x2d, 0x31, 0xcc,
|
||||
};
|
||||
static const uint8_t slh_dsa_sha2_128s_0_pub[] = {
|
||||
0xcb, 0x23, 0xeb, 0x45, 0x52, 0x9e, 0x00, 0xd5, 0xf5, 0xe9, 0x51, 0x50, 0x7a, 0x9b, 0x90, 0xe9,
|
||||
0x8b, 0x6e, 0x7a, 0x28, 0x4b, 0xa3, 0xf6, 0x3a, 0x69, 0xe6, 0x9a, 0x78, 0x90, 0x83, 0xbe, 0xf6,
|
||||
};
|
||||
static const uint8_t slh_dsa_sha2_128s_0_msg[] = {
|
||||
0x9D, 0xDF
|
||||
};
|
||||
static const uint8_t slh_dsa_sha2_128s_0_sig_digest[] = {
|
||||
0xc7, 0xdf, 0xf0, 0xed, 0x25, 0x38, 0x49, 0xef, 0x51, 0x1e, 0x90, 0xbe, 0x0e, 0x2e, 0xb7, 0x71,
|
||||
0x65, 0x98, 0x91, 0x23, 0x17, 0x52, 0x9a, 0x61, 0xda, 0xe4, 0x32, 0x9b, 0xf1, 0x49, 0xef, 0x8b,
|
||||
};
|
||||
|
||||
/* We can only use the hss tests that have a single level here */
|
||||
static SLH_DSA_ACVP_TEST_DATA slh_dsa_testdata[] = {
|
||||
SLH_DSA_ACVP_ITEM(slh_dsa_sha2_128s_0, "SLH-DSA-SHA2-128s"),
|
||||
};
|
123
test/slh_dsa_test.c
Normal file
123
test/slh_dsa_test.c
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "crypto/slh_dsa.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "testutil.h"
|
||||
#include "slh_dsa.inc"
|
||||
|
||||
static OSSL_LIB_CTX *libctx = NULL;
|
||||
|
||||
static EVP_PKEY *slh_dsa_pubkey_from_data(const char *alg,
|
||||
const unsigned char *data, size_t datalen)
|
||||
{
|
||||
int ret;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
EVP_PKEY *key = NULL;
|
||||
OSSL_PARAM params[2];
|
||||
|
||||
params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
|
||||
(unsigned char *)data, datalen);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
ret = TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, alg, NULL))
|
||||
&& TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
|
||||
&& (EVP_PKEY_fromdata(ctx, &key, EVP_PKEY_PUBLIC_KEY, params) == 1);
|
||||
if (ret == 0) {
|
||||
EVP_PKEY_free(key);
|
||||
key = NULL;
|
||||
}
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return key;
|
||||
}
|
||||
|
||||
static int slh_dsa_bad_pub_len_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
SLH_DSA_ACVP_TEST_DATA *td = &slh_dsa_testdata[0];
|
||||
EVP_PKEY *pkey = NULL;
|
||||
size_t pub_len = 0;
|
||||
unsigned char pubdata[64 + 1];
|
||||
|
||||
if (!TEST_size_t_le(td->pub_len, sizeof(pubdata)))
|
||||
goto end;
|
||||
|
||||
OPENSSL_cleanse(pubdata, sizeof(pubdata));
|
||||
memcpy(pubdata, td->pub, td->pub_len);
|
||||
|
||||
if (!TEST_ptr_null(pkey = slh_dsa_pubkey_from_data(td->alg, pubdata,
|
||||
td->pub_len - 1))
|
||||
|| !TEST_ptr_null(pkey = slh_dsa_pubkey_from_data(td->alg, pubdata,
|
||||
td->pub_len + 1)))
|
||||
goto end;
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
if (ret == 0)
|
||||
TEST_note("Incorrectly accepted public key of length %u (expected %u)",
|
||||
(unsigned)pub_len, (unsigned)td->pub_len);
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret == 1;
|
||||
}
|
||||
|
||||
static int slh_dsa_key_eq_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_PKEY *key[2] = { NULL, NULL };
|
||||
SLH_DSA_ACVP_TEST_DATA *td1 = &slh_dsa_testdata[0];
|
||||
#ifndef OPENSSL_NO_EC
|
||||
EVP_PKEY *eckey = NULL;
|
||||
#endif
|
||||
|
||||
if (!TEST_ptr(key[0] = slh_dsa_pubkey_from_data(td1->alg, td1->pub, td1->pub_len))
|
||||
|| !TEST_ptr(key[1] = slh_dsa_pubkey_from_data(td1->alg, td1->pub, td1->pub_len)))
|
||||
goto end;
|
||||
|
||||
ret = TEST_int_eq(EVP_PKEY_eq(key[0], key[1]), 1);
|
||||
if (ret == 0)
|
||||
goto end;
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
if (!TEST_ptr(eckey = EVP_PKEY_Q_keygen(libctx, NULL, "EC", "P-256")))
|
||||
goto end;
|
||||
ret = TEST_int_ne(EVP_PKEY_eq(key[0], eckey), 1);
|
||||
EVP_PKEY_free(eckey);
|
||||
#endif
|
||||
end:
|
||||
EVP_PKEY_free(key[1]);
|
||||
EVP_PKEY_free(key[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int slh_dsa_key_validate_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
SLH_DSA_ACVP_TEST_DATA *td = &slh_dsa_testdata[0];
|
||||
EVP_PKEY_CTX *vctx = NULL;
|
||||
EVP_PKEY *key = NULL;
|
||||
|
||||
if (!TEST_ptr(key = slh_dsa_pubkey_from_data(td->alg, td->pub, td->pub_len)))
|
||||
return 0;
|
||||
if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL)))
|
||||
goto end;
|
||||
ret = TEST_int_eq(EVP_PKEY_check(vctx), 1);
|
||||
EVP_PKEY_CTX_free(vctx);
|
||||
end:
|
||||
EVP_PKEY_free(key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
ADD_TEST(slh_dsa_bad_pub_len_test);
|
||||
ADD_TEST(slh_dsa_key_validate_test);
|
||||
ADD_TEST(slh_dsa_key_eq_test);
|
||||
return 1;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user