1313#include <openssl/bio.h>
1414#include <openssl/crypto.h>
1515#include <openssl/x509.h>
16-
16+ #include <openssl/core_names.h>
1717#include "bc_err_codes.h"
1818#include "key_spec.h"
1919#include "ops.h"
@@ -50,7 +50,6 @@ int32_t asn1_writer_get_content(asn1_ctx *ctx, uint8_t *output, size_t *written,
5050 * written = BIO_get_mem_data (ctx -> buffer , & buffer );
5151
5252 if (output != NULL ) {
53-
5453 if (output_len != * written ) {
5554 return JO_OUTPUT_OUT_OF_RANGE ;
5655 }
@@ -77,13 +76,175 @@ int32_t asn1_writer_encode_public_key(asn1_ctx *ctx, key_spec *key_spec, size_t
7776 return 1 ;
7877}
7978
80- int32_t asn1_writer_encode_private_key (asn1_ctx * ctx , key_spec * key_spec , size_t * buf_len ) {
79+ static uint8_t mldsa44 [] = {
80+ 48 , 52 , 2 , 1 , 0 , 48 , 11 , 6 , 9 , 96 , -122 , 72 , 1 , 101 ,
81+ 3 , 4 , 3 , 17 , 4 , 34 , -128 , 32 , 0 , 0 , 0 , 24 , -114 ,
82+ -53 , -113 , 95 , -119 , -16 , 39 , 21 , 113 , 55 , -26 , 114 ,
83+ -74 , -30 , -20 , -39 , 107 , 62 , 87 , 20 , 41 , 34 , 90 , -18 ,
84+ -39 , -100 , -91 , -10
85+ }; // Seed at byte 22 for 32
86+
87+ static uint8_t mldsa65 [] = {
88+ 48 , 52 , 2 , 1 , 0 , 48 , 11 , 6 , 9 , 96 , -122 , 72 , 1 , 101 ,
89+ 3 , 4 , 3 , 18 , 4 , 34 , -128 , 32 , 8 , -114 , 106 , -34 , 33 ,
90+ -98 , 52 , 82 , -49 , 38 , 83 , 64 , 94 , -40 , -4 , 34 , -102 ,
91+ 114 , -44 , 79 , 63 , -108 , 20 , 90 , 127 , 120 , -99 , -103 ,
92+ -60 , -128 , -41 , 87
93+ };
94+
95+ static uint8_t mldsa87 [] = {
96+ 48 , 52 , 2 , 1 , 0 , 48 , 11 , 6 , 9 , 96 , -122 , 72 , 1 , 101 ,
97+ 3 , 4 , 3 , 19 , 4 , 34 , -128 , 32 , -53 , 1 , -80 , -43 , -69 ,
98+ -53 , -31 , -23 , 13 , 107 , 112 , 73 , -105 , -65 , 120 , 123 ,
99+ 87 , 81 , 58 , 107 , 18 , 65 , -62 , -8 , 92 , 36 , 126 , -97 ,
100+ -4 , 64 , 93 , -86
101+ };
102+
103+
104+ static uint8_t mlkem512 [] = {
105+ 48 , 84 , 2 , 1 , 0 , 48 , 11 , 6 , 9 , 96 , -122 , 72 , 1 , 101 , 3 ,
106+ 4 , 4 , 1 , 4 , 66 , -128 , 64 , -21 , -50 , 86 , -11 , -120 , -111 ,
107+ 60 , 38 , 98 , 62 , 7 , 9 , 64 , 49 , -67 , -88 , -37 , 65 , 3 , -70 ,
108+ -119 , -109 , -22 , 120 , -69 , 95 , 89 , 72 , -79 , -53 , -100 ,
109+ -112 , -103 , 49 , -118 , 107 , -10 , 52 , -4 , 35 , -69 , 17 , 67 ,
110+ 58 , -24 , -123 , -77 , -70 , 74 , 125 , -83 , -33 , -126 , 34 , 32 ,
111+ 24 , 28 , -99 , -53 , 31 , 23 , 97 , -59 , -111
112+ };
113+
114+ static uint8_t mlkem768 [] = {
115+ 48 , 84 , 2 , 1 , 0 , 48 , 11 , 6 , 9 , 96 , -122 , 72 , 1 , 101 , 3 ,
116+ 4 , 4 , 2 , 4 , 66 , -128 , 64 , -70 , -57 , -85 , 79 , -37 , -43 ,
117+ 102 , 66 , 26 , -118 , -59 , 37 , 104 , 86 , -89 , -108 , 45 , -25 ,
118+ 13 , 61 , -80 , 10 , -55 , 30 , 47 , -57 , 117 , -72 , -44 , -66 ,
119+ 61 , 88 , -128 , 21 , -88 , 9 , -1 , 26 , -103 , 33 , -26 , 72 , -32 ,
120+ -33 , -72 , 26 , -101 , 64 , 28 , -21 , 94 , 113 , 22 , -70 , -20 ,
121+ -78 , 23 , 40 , 16 , 12 , 60 , 6 , -109 , -89
122+ }; // Seed at byte 22 for 64
123+
124+
125+ static uint8_t mlkem1024 [] = {
126+ 48 , 84 , 2 , 1 , 0 , 48 , 11 , 6 , 9 , 96 , -122 , 72 , 1 , 101 , 3 , 4 ,
127+ 4 , 3 , 4 , 66 , -128 , 64 , -26 , -73 , 52 , -19 , 111 , 116 , 81 , 6 ,
128+ 72 , -100 , 120 , -75 , -90 , -118 , 44 , -100 , 59 , 41 , -35 , 81 ,
129+ -109 , -121 , -42 , -37 , -102 , 11 , -9 , 3 , -50 , -59 , 30 , -15 ,
130+ 9 , 46 , -71 , 106 , -45 , 2 , -126 , 64 , 108 , 114 , -67 , -91 , -68 ,
131+ 38 , -77 , 97 , -56 , 126 , -8 , -43 , 127 , -30 , 2 , -60 , 95 , -74 ,
132+ 125 , -101 , 88 , 35 , -17 , 89
133+ };
134+
135+
136+ int32_t asn1_writer_encode_private_key (asn1_ctx * ctx , key_spec * key_spec , size_t * buf_len , int encoding_option ) {
81137 assert (ctx != NULL );
82138 assert (key_spec != NULL );
83139 assert (key_spec -> key != NULL );
84140
85- if (!i2d_PrivateKey_bio (ctx -> buffer , key_spec -> key )) {
86- return 0 ;
141+ switch (encoding_option ) {
142+ case PRIVATE_KEY_DEFAULT_ENCODING :
143+ if (!i2d_PrivateKey_bio (ctx -> buffer , key_spec -> key )) {
144+ return 0 ;
145+ }
146+ break ;
147+ case PRIVATE_KEY_SEED_ONLY_ENCODING :
148+
149+ // NB hack until official support in OpenSSL
150+ // This is not intended to be robust implementation and will be replaced
151+
152+ if (EVP_PKEY_is_a (key_spec -> key , "ML-DSA-44" )) {
153+ uint8_t b [sizeof (mldsa44 )];
154+ memcpy (b , mldsa44 , sizeof (mldsa44 ));
155+
156+ if (
157+ 1 != EVP_PKEY_get_octet_string_param (
158+ key_spec -> key ,
159+ OSSL_PKEY_PARAM_ML_DSA_SEED , b + 22 , 32 , NULL )) {
160+ return 0 ;
161+ }
162+
163+ if (BIO_write (ctx -> buffer , b , sizeof (mldsa44 )) < 0 ) {
164+ return 0 ;
165+ }
166+ OPENSSL_cleanse (b , sizeof (mldsa44 ));
167+ } else if (EVP_PKEY_is_a (key_spec -> key , "ML-DSA-65" )) {
168+ uint8_t b [sizeof (mldsa65 )];
169+ memcpy (b , mldsa65 , sizeof (mldsa65 ));
170+
171+ if (
172+ 1 != EVP_PKEY_get_octet_string_param (
173+ key_spec -> key ,
174+ OSSL_PKEY_PARAM_ML_DSA_SEED , b + 22 , 32 , NULL )) {
175+ return 0 ;
176+ }
177+
178+ if (BIO_write (ctx -> buffer , b , sizeof (mldsa65 )) < 0 ) {
179+ return 0 ;
180+ }
181+ OPENSSL_cleanse (b , sizeof (mldsa65 ));
182+ } else if (EVP_PKEY_is_a (key_spec -> key , "ML-DSA-87" )) {
183+ uint8_t b [sizeof (mldsa87 )];
184+ memcpy (b , mldsa87 , sizeof (mldsa87 ));
185+
186+ if (
187+ 1 != EVP_PKEY_get_octet_string_param (
188+ key_spec -> key ,
189+ OSSL_PKEY_PARAM_ML_DSA_SEED , b + 22 , 32 , NULL )) {
190+ return 0 ;
191+ }
192+
193+ if (BIO_write (ctx -> buffer , b , sizeof (mldsa87 )) < 0 ) {
194+ return 0 ;
195+ }
196+ OPENSSL_cleanse (b , sizeof (mldsa87 ));
197+ } else if (EVP_PKEY_is_a (key_spec -> key , "ML-KEM-512" )) {
198+ uint8_t b [sizeof (mlkem512 )];
199+ memcpy (b , mlkem512 , sizeof (mlkem512 ));
200+
201+ if (
202+ 1 != EVP_PKEY_get_octet_string_param (
203+ key_spec -> key ,
204+ OSSL_PKEY_PARAM_ML_DSA_SEED , b + 22 , 64 , NULL )) {
205+ return JO_OPENSSL_ERROR ;
206+ }
207+
208+ if (BIO_write (ctx -> buffer , b , sizeof (mlkem512 )) < 0 ) {
209+ return 0 ;
210+ }
211+ OPENSSL_cleanse (b , sizeof (mlkem512 ));
212+ } else if (EVP_PKEY_is_a (key_spec -> key , "ML-KEM-768" )) {
213+ uint8_t b [sizeof (mlkem768 )];
214+ memcpy (b , mlkem768 , sizeof (mlkem768 ));
215+
216+ if (
217+ 1 != EVP_PKEY_get_octet_string_param (
218+ key_spec -> key ,
219+ OSSL_PKEY_PARAM_ML_DSA_SEED , b + 22 , 64 , NULL )) {
220+ return 0 ;
221+ }
222+
223+ if (BIO_write (ctx -> buffer , b , sizeof (mlkem768 )) < 0 ) {
224+ return 0 ;
225+ }
226+ OPENSSL_cleanse (b , sizeof (mlkem768 ));
227+ } else if (EVP_PKEY_is_a (key_spec -> key , "ML-KEM-1024" )) {
228+ uint8_t b [sizeof (mlkem1024 )];
229+ memcpy (b , mlkem1024 , sizeof (mlkem1024 ));
230+
231+ if (
232+ 1 != EVP_PKEY_get_octet_string_param (
233+ key_spec -> key ,
234+ OSSL_PKEY_PARAM_ML_DSA_SEED , b + 22 , 64 , NULL )) {
235+ return 0 ;
236+ }
237+
238+ if (BIO_write (ctx -> buffer , b , sizeof (mlkem1024 )) < 0 ) {
239+ return 0 ;
240+ }
241+ OPENSSL_cleanse (b , sizeof (mlkem1024 ));
242+ } else {
243+ return 0 ;
244+ }
245+ break ;
246+ default :
247+ return 0 ;
87248 }
88249
89250
0 commit comments