1 /*
2  * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <openssl/core_dispatch.h>
11 #include "crypto/lms.h"
12 #include <string.h>
13 
14 /**
15  * @brief Create a new LMS_KEY object
16  *
17  * @param libctx A OSSL_LIB_CTX object used for fetching algorithms.
18  * @returns The new LMS_KEY object on success, or NULL on malloc failure
19  */
ossl_lms_key_new(OSSL_LIB_CTX * libctx)20 LMS_KEY *ossl_lms_key_new(OSSL_LIB_CTX *libctx)
21 {
22     LMS_KEY *ret = OPENSSL_zalloc(sizeof(LMS_KEY));
23 
24     if (ret != NULL)
25         ret->libctx = libctx;
26     return ret;
27 }
28 
29 /**
30  * @brief Destroy a LMS_KEY object
31  */
ossl_lms_key_free(LMS_KEY * lmskey)32 void ossl_lms_key_free(LMS_KEY *lmskey)
33 {
34     LMS_PUB_KEY *pub;
35 
36     if (lmskey == NULL)
37         return;
38 
39     pub = &lmskey->pub;
40     OPENSSL_free(pub->encoded);
41     OPENSSL_free(lmskey);
42 }
43 
44 /**
45  * @brief Are 2 LMS public keys equal?
46  *
47  * To be equal the keys must have the same LMS_PARAMS, LM_OTS_PARAMS and
48  * encoded public keys.
49  *
50  * @param key1 A LMS_KEY object
51  * @param key2 A LMS_KEY object
52  * @param selection Only OSSL_KEYMGMT_SELECT_PUBLIC_KEY is supported
53  * @returns 1 if the keys are equal otherwise it returns 0.
54  */
ossl_lms_key_equal(const LMS_KEY * key1,const LMS_KEY * key2,int selection)55 int ossl_lms_key_equal(const LMS_KEY *key1, const LMS_KEY *key2, int selection)
56 {
57     int ok = 1;
58 
59     if (key1->lms_params != key2->lms_params
60             || key1->ots_params != key2->ots_params)
61         return 0;
62 
63     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
64         if (key1->pub.encodedlen != key2->pub.encodedlen)
65             return 0;
66         ok = (key1->pub.encodedlen == 0)
67             || (memcmp(key1->pub.encoded, key2->pub.encoded,
68                        key1->pub.encodedlen) == 0);
69     }
70     return ok;
71 }
72 
73 /**
74  * @brief Is a LMS_KEY valid.
75  *
76  * @param key A LMS_KEY object
77  * @param selection Currently only supports |OSSL_KEYMGMT_SELECT_PUBLIC_KEY|
78  * @returns 1 if a LMS_KEY contains valid key data.
79  */
ossl_lms_key_valid(const LMS_KEY * key,int selection)80 int ossl_lms_key_valid(const LMS_KEY *key, int selection)
81 {
82     if (key == NULL)
83         return 0;
84 
85     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
86         return key->pub.encoded != NULL && key->pub.encodedlen != 0;
87     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
88         return 0; /* a private key that doesn't exist can't be valid */
89     return 1;
90 }
91 
92 /**
93  * @brief Does a LMS_KEY object contain a public key.
94  *
95  * @param key A LMS_KEY object
96  * @param selection Currently only supports |OSSL_KEYMGMT_SELECT_PUBLIC_KEY|
97  * @returns 1 if a LMS_KEY contains public key data, or 0 otherwise.
98  */
ossl_lms_key_has(const LMS_KEY * key,int selection)99 int ossl_lms_key_has(const LMS_KEY *key, int selection)
100 {
101     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
102         return (key != NULL) && (key->pub.K != NULL);
103     /* There is no private key currently */
104     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
105         return 0;
106     return 1;
107 }
108