File: lms.h

package info (click to toggle)
openssl 3.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 148,104 kB
  • sloc: ansic: 612,658; perl: 248,939; asm: 6,332; sh: 1,755; pascal: 997; python: 648; makefile: 551; lisp: 35; ruby: 16; cpp: 10; sed: 6
file content (160 lines) | stat: -rw-r--r-- 5,907 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * Copyright 2025 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>

/*
 * 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;
    /*
     * The size of the shift needed to move the checksum so
     * that it appears in the checksum digits.
     * See RFC 8554 Appendix B.  LM-OTS Parameter Options
     */
    uint32_t ls;
    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;

typedef 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;
} LMS_KEY;

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);
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 *pub, 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 */