Reviewed-by: Hugo Landau <hlandau@devever.net> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Paul Dale <ppzgs1@gmail.com> (Merged from https://github.com/openssl/openssl/pull/25598)
157 lines
5.7 KiB
C
157 lines
5.7 KiB
C
/*
|
|
* 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 LMS/LM_OTS functions for other submodules,
|
|
* not for application use
|
|
*/
|
|
|
|
#ifndef OSSL_CRYPTO_LMS_H
|
|
# define OSSL_CRYPTO_LMS_H
|
|
# pragma once
|
|
# ifndef OPENSSL_NO_LMS
|
|
# include "types.h"
|
|
# include <openssl/params.h>
|
|
# include "internal/refcount.h"
|
|
|
|
/*
|
|
* Numeric identifiers associated with Leighton-Micali Signatures (LMS)
|
|
* parameter sets are defined in
|
|
* https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml
|
|
* which is referenced from SP800-208.
|
|
*/
|
|
# define OSSL_LMS_TYPE_SHA256_N32_H5 0x00000005
|
|
# define OSSL_LMS_TYPE_SHA256_N32_H10 0x00000006
|
|
# define OSSL_LMS_TYPE_SHA256_N32_H15 0x00000007
|
|
# define OSSL_LMS_TYPE_SHA256_N32_H20 0x00000008
|
|
# define OSSL_LMS_TYPE_SHA256_N32_H25 0x00000009
|
|
# define OSSL_LMS_TYPE_SHA256_N24_H5 0x0000000A
|
|
# define OSSL_LMS_TYPE_SHA256_N24_H10 0x0000000B
|
|
# define OSSL_LMS_TYPE_SHA256_N24_H15 0x0000000C
|
|
# define OSSL_LMS_TYPE_SHA256_N24_H20 0x0000000D
|
|
# define OSSL_LMS_TYPE_SHA256_N24_H25 0x0000000E
|
|
# define OSSL_LMS_TYPE_SHAKE_N32_H5 0x0000000F
|
|
# define OSSL_LMS_TYPE_SHAKE_N32_H10 0x00000010
|
|
# define OSSL_LMS_TYPE_SHAKE_N32_H15 0x00000011
|
|
# define OSSL_LMS_TYPE_SHAKE_N32_H20 0x00000012
|
|
# define OSSL_LMS_TYPE_SHAKE_N32_H25 0x00000013
|
|
# define OSSL_LMS_TYPE_SHAKE_N24_H5 0x00000014
|
|
# define OSSL_LMS_TYPE_SHAKE_N24_H10 0x00000015
|
|
# define OSSL_LMS_TYPE_SHAKE_N24_H15 0x00000016
|
|
# define OSSL_LMS_TYPE_SHAKE_N24_H20 0x00000017
|
|
# define OSSL_LMS_TYPE_SHAKE_N24_H25 0x00000018
|
|
|
|
# define OSSL_LM_OTS_TYPE_SHA256_N32_W1 0x00000001
|
|
# define OSSL_LM_OTS_TYPE_SHA256_N32_W2 0x00000002
|
|
# define OSSL_LM_OTS_TYPE_SHA256_N32_W4 0x00000003
|
|
# define OSSL_LM_OTS_TYPE_SHA256_N32_W8 0x00000004
|
|
# define OSSL_LM_OTS_TYPE_SHA256_N24_W1 0x00000005
|
|
# define OSSL_LM_OTS_TYPE_SHA256_N24_W2 0x00000006
|
|
# define OSSL_LM_OTS_TYPE_SHA256_N24_W4 0x00000007
|
|
# define OSSL_LM_OTS_TYPE_SHA256_N24_W8 0x00000008
|
|
# define OSSL_LM_OTS_TYPE_SHAKE_N32_W1 0x00000009
|
|
# define OSSL_LM_OTS_TYPE_SHAKE_N32_W2 0x0000000A
|
|
# define OSSL_LM_OTS_TYPE_SHAKE_N32_W4 0x0000000B
|
|
# define OSSL_LM_OTS_TYPE_SHAKE_N32_W8 0x0000000C
|
|
# define OSSL_LM_OTS_TYPE_SHAKE_N24_W1 0x0000000D
|
|
# define OSSL_LM_OTS_TYPE_SHAKE_N24_W2 0x0000000E
|
|
# define OSSL_LM_OTS_TYPE_SHAKE_N24_W4 0x0000000F
|
|
# define OSSL_LM_OTS_TYPE_SHAKE_N24_W8 0x00000010
|
|
|
|
/* Constants used for verifying */
|
|
# define LMS_SIZE_q 4
|
|
|
|
/* XDR sizes when encoding and decoding */
|
|
# define LMS_SIZE_I 16
|
|
# define LMS_SIZE_LMS_TYPE 4
|
|
# define LMS_SIZE_OTS_TYPE 4
|
|
# define LMS_MAX_DIGEST_SIZE 32
|
|
# define LMS_MAX_PUBKEY \
|
|
(LMS_SIZE_LMS_TYPE + LMS_SIZE_OTS_TYPE + LMS_SIZE_I + LMS_MAX_DIGEST_SIZE)
|
|
|
|
/*
|
|
* Refer to RFC 8554 Section 4.1.
|
|
* See also lm_ots_params[]
|
|
*/
|
|
typedef struct lm_ots_params_st {
|
|
/*
|
|
* The OTS type associates an id with a set of OTS parameters
|
|
* e.g. OSSL_LM_OTS_TYPE_SHAKE_N32_W1
|
|
*/
|
|
uint32_t lm_ots_type;
|
|
uint32_t n; /* Hash output size in bytes (32 or 24) */
|
|
/*
|
|
* The width of the Winternitz coefficients in bits. One of (1, 2, 4, 8)
|
|
* Higher values of w are slower (~2^w computations) but have smaller
|
|
* signatures.
|
|
*/
|
|
uint32_t w;
|
|
/*
|
|
* The number of n-byte elements used for an LMOTS signature.
|
|
* One of (265, 133, 67, 34) for n = 32, for w=1,2,4,8
|
|
* One of (200, 101, 51, 26) for n = 24, for w=1,2,4,8
|
|
*/
|
|
uint32_t p;
|
|
const char *digestname; /* Hash Name */
|
|
} LM_OTS_PARAMS;
|
|
|
|
/* See lms_params[] */
|
|
typedef struct lms_params_st {
|
|
/*
|
|
* The lms type associates an id with a set of parameters to define the
|
|
* Digest and Height of a LMS tree.
|
|
* e.g, OSSL_LMS_TYPE_SHA256_N24_H25
|
|
*/
|
|
uint32_t lms_type;
|
|
const char *digestname; /* One of SHA256, SHA256-192, or SHAKE256 */
|
|
uint32_t n; /* The Digest size (either 24 or 32), Useful for setting up SHAKE */
|
|
uint32_t h; /* The height of a LMS tree which is one of 5, 10, 15, 20, 25) */
|
|
} LMS_PARAMS;
|
|
|
|
typedef struct lms_pub_key_st {
|
|
/*
|
|
* A buffer containing an encoded public key of the form
|
|
* u32str(lmstype) || u32str(otstype) || I[16] || K[n]
|
|
*/
|
|
unsigned char *encoded; /* encoded public key data */
|
|
size_t encodedlen;
|
|
/*
|
|
* K is the LMS tree's root public key (Called T(1))
|
|
* It is n bytes long (the hash size).
|
|
* It is a pointer into the encoded buffer
|
|
*/
|
|
unsigned char *K;
|
|
} LMS_PUB_KEY;
|
|
|
|
struct lms_key_st {
|
|
const LMS_PARAMS *lms_params;
|
|
const LM_OTS_PARAMS *ots_params;
|
|
OSSL_LIB_CTX *libctx;
|
|
unsigned char *Id; /* A pointer to 16 bytes (I[16]) */
|
|
LMS_PUB_KEY pub;
|
|
CRYPTO_REF_COUNT references;
|
|
};
|
|
|
|
const LMS_PARAMS *ossl_lms_params_get(uint32_t lms_type);
|
|
const LM_OTS_PARAMS *ossl_lm_ots_params_get(uint32_t ots_type);
|
|
|
|
LMS_KEY *ossl_lms_key_new(OSSL_LIB_CTX *libctx);
|
|
int ossl_lms_key_up_ref(LMS_KEY *key);
|
|
void ossl_lms_key_free(LMS_KEY *lmskey);
|
|
int ossl_lms_key_equal(const LMS_KEY *key1, const LMS_KEY *key2, int selection);
|
|
int ossl_lms_key_valid(const LMS_KEY *key, int selection);
|
|
int ossl_lms_key_has(const LMS_KEY *key, int selection);
|
|
|
|
int ossl_lms_pubkey_from_params(const OSSL_PARAM params[], LMS_KEY *lmskey);
|
|
int ossl_lms_pubkey_decode(const unsigned char *pub, size_t publen,
|
|
LMS_KEY *lmskey);
|
|
size_t ossl_lms_pubkey_length(const unsigned char *data, size_t datalen);
|
|
|
|
# endif /* OPENSSL_NO_LMS */
|
|
#endif /* OSSL_CRYPTO_LMS_H */
|