-
Notifications
You must be signed in to change notification settings - Fork 412
Expand file tree
/
Copy pathOSSLMLDSAPublicKey.cpp
More file actions
148 lines (122 loc) · 3.37 KB
/
Copy pathOSSLMLDSAPublicKey.cpp
File metadata and controls
148 lines (122 loc) · 3.37 KB
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
/*****************************************************************************
OSSLMLDSAPublicKey.cpp
OpenSSL ML-DSA public key class
*****************************************************************************/
#include "config.h"
#ifdef WITH_ML_DSA
#include "log.h"
#include "OSSLMLDSAPublicKey.h"
#include "MLDSAParameters.h"
#include "OSSLUtil.h"
#include <openssl/evp.h>
#include <openssl/core_names.h>
#include <string.h>
// Constructors
OSSLMLDSAPublicKey::OSSLMLDSAPublicKey()
{
pkey = NULL;
}
OSSLMLDSAPublicKey::OSSLMLDSAPublicKey(const EVP_PKEY* inEVPPKEY)
{
pkey = NULL;
setFromOSSL(inEVPPKEY);
}
// Destructor
OSSLMLDSAPublicKey::~OSSLMLDSAPublicKey()
{
if (pkey != NULL)
{
EVP_PKEY_free(pkey);
pkey = NULL;
}
}
OSSLMLDSAPublicKey::OSSLMLDSAPublicKey(OSSLMLDSAPublicKey&& other) noexcept
: MLDSAPublicKey(std::move(other)), pkey(other.pkey)
{
other.pkey = NULL;
}
OSSLMLDSAPublicKey& OSSLMLDSAPublicKey::operator=(OSSLMLDSAPublicKey&& other) noexcept
{
if (this != &other)
{
// move base
MLDSAPublicKey::operator=(std::move(other));
// release current
if (pkey) { EVP_PKEY_free(pkey); }
// steal
pkey = other.pkey;
other.pkey = NULL;
}
return *this;
}
// The type
/*static*/ const char* OSSLMLDSAPublicKey::type = "OpenSSL ML-DSA Public Key";
// Set from OpenSSL representation
void OSSLMLDSAPublicKey::setFromOSSL(const EVP_PKEY* inEVPPKEY)
{
// let's use max pub length
uint8_t localPub[MLDSAParameters::ML_DSA_87_PUB_LENGTH];
size_t pub_len;
int rv = EVP_PKEY_get_octet_string_param(inEVPPKEY, OSSL_PKEY_PARAM_PUB_KEY,
localPub, sizeof(localPub), &pub_len);
if(!rv) {
ERROR_MSG("Could not get ML-DSA public key, rv: %d", rv);
return;
}
ByteString pubBS = ByteString(localPub, pub_len);
setValue(pubBS);
}
// Check if the key is of the given type
bool OSSLMLDSAPublicKey::isOfType(const char* inType)
{
return !strcmp(OSSLMLDSAPublicKey::type, inType) || MLDSAPublicKey::isOfType(inType);
}
void OSSLMLDSAPublicKey::setValue(const ByteString& inValue)
{
MLDSAPublicKey::setValue(inValue);
if (pkey)
{
EVP_PKEY_free(pkey);
pkey = NULL;
}
}
// Retrieve the OpenSSL representation of the key
EVP_PKEY* OSSLMLDSAPublicKey::getOSSLKey()
{
if (pkey == NULL) createOSSLKey();
return pkey;
}
// Create the OpenSSL representation of the key
void OSSLMLDSAPublicKey::createOSSLKey()
{
if (pkey != NULL) return;
ByteString localValue = getValue();
const char* name = OSSL::mldsaParameterSet2Name(getParameterSet());
int selection = 0;
EVP_PKEY_CTX *ctx = NULL;
OSSL_PARAM params[3], *p = params;
*p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
localValue.byte_str(), localValue.size());
selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
*p = OSSL_PARAM_construct_end();
// Use the default provider for internal ML-DSA key reconstruction
ctx = EVP_PKEY_CTX_new_from_name(NULL, name, "provider=default");
if (ctx == NULL) {
ERROR_MSG("Could not create context");
return;
}
int rv = EVP_PKEY_fromdata_init(ctx);
if (!rv) {
ERROR_MSG("Could not EVP_PKEY_fromdata_init:%d", rv);
EVP_PKEY_CTX_free(ctx);
return;
}
rv = EVP_PKEY_fromdata(ctx, &pkey, selection, params);
if (!rv) {
ERROR_MSG("Could not EVP_PKEY_fromdata:%d", rv);
EVP_PKEY_CTX_free(ctx);
return;
}
EVP_PKEY_CTX_free(ctx);
}
#endif