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:
slontis 2024-11-06 14:22:45 +11:00 committed by Tomas Mraz
parent 16395ee9cc
commit 34f4cacc8f
18 changed files with 612 additions and 1 deletions

View File

@ -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

View File

@ -0,0 +1,7 @@
LIBS=../../libcrypto
$COMMON=slh_dsa_key.c slh_params.c
IF[{- !$disabled{'slh_dsa'} -}]
SOURCE[../../libcrypto]=$COMMON
ENDIF

View 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;
}

View 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;
};

View 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"

View 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;
}

View 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
View 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 */

View File

@ -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;

View File

@ -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 }
};

View File

@ -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[];

View File

@ -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"

View File

@ -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

View 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);

View File

@ -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

View 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
View 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
View 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;
}