/src/openssl31/providers/common/der/der_rsa_key.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2020-2022 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 | | /* |
11 | | * RSA low level APIs are deprecated for public use, but still ok for |
12 | | * internal use. |
13 | | */ |
14 | | #include "internal/deprecated.h" |
15 | | |
16 | | #include <openssl/obj_mac.h> |
17 | | #include "internal/cryptlib.h" |
18 | | #include "prov/der_rsa.h" |
19 | | #include "prov/der_digests.h" |
20 | | |
21 | | /* More complex pre-compiled sequences. */ |
22 | | |
23 | | /*- |
24 | | * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1 |
25 | | * |
26 | | * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { |
27 | | * { OID id-sha1 PARAMETERS NULL }| |
28 | | * { OID id-sha224 PARAMETERS NULL }| |
29 | | * { OID id-sha256 PARAMETERS NULL }| |
30 | | * { OID id-sha384 PARAMETERS NULL }| |
31 | | * { OID id-sha512 PARAMETERS NULL }| |
32 | | * { OID id-sha512-224 PARAMETERS NULL }| |
33 | | * { OID id-sha512-256 PARAMETERS NULL }, |
34 | | * ... -- Allows for future expansion -- |
35 | | * } |
36 | | */ |
37 | | #define DER_V_NULL DER_P_NULL, 0 |
38 | | #define DER_SZ_NULL 2 |
39 | | |
40 | | /* |
41 | | * The names for the hash function AlgorithmIdentifiers are borrowed and |
42 | | * expanded from https://tools.ietf.org/html/rfc4055#section-2.1 |
43 | | * |
44 | | * sha1Identifier AlgorithmIdentifier ::= { id-sha1, NULL } |
45 | | * sha224Identifier AlgorithmIdentifier ::= { id-sha224, NULL } |
46 | | * sha256Identifier AlgorithmIdentifier ::= { id-sha256, NULL } |
47 | | * sha384Identifier AlgorithmIdentifier ::= { id-sha384, NULL } |
48 | | * sha512Identifier AlgorithmIdentifier ::= { id-sha512, NULL } |
49 | | */ |
50 | | /* |
51 | | * NOTE: Some of the arrays aren't used other than inside sizeof(), which |
52 | | * clang complains about (-Wno-unneeded-internal-declaration). To get |
53 | | * around that, we make them non-static, and declare them an extra time to |
54 | | * avoid compilers complaining about definitions without declarations. |
55 | | */ |
56 | | #define DER_AID_V_sha1Identifier \ |
57 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
58 | | DER_OID_SZ_id_sha1 + DER_SZ_NULL, \ |
59 | | DER_OID_V_id_sha1, \ |
60 | | DER_V_NULL |
61 | | extern const unsigned char ossl_der_aid_sha1Identifier[]; |
62 | | const unsigned char ossl_der_aid_sha1Identifier[] = { |
63 | | DER_AID_V_sha1Identifier |
64 | | }; |
65 | | #define DER_AID_SZ_sha1Identifier sizeof(ossl_der_aid_sha1Identifier) |
66 | | |
67 | | #define DER_AID_V_sha224Identifier \ |
68 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
69 | | DER_OID_SZ_id_sha224 + DER_SZ_NULL, \ |
70 | | DER_OID_V_id_sha224, \ |
71 | | DER_V_NULL |
72 | | extern const unsigned char ossl_der_aid_sha224Identifier[]; |
73 | | const unsigned char ossl_der_aid_sha224Identifier[] = { |
74 | | DER_AID_V_sha224Identifier |
75 | | }; |
76 | | #define DER_AID_SZ_sha224Identifier sizeof(ossl_der_aid_sha224Identifier) |
77 | | |
78 | | #define DER_AID_V_sha256Identifier \ |
79 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
80 | | DER_OID_SZ_id_sha256 + DER_SZ_NULL, \ |
81 | | DER_OID_V_id_sha256, \ |
82 | | DER_V_NULL |
83 | | extern const unsigned char ossl_der_aid_sha256Identifier[]; |
84 | | const unsigned char ossl_der_aid_sha256Identifier[] = { |
85 | | DER_AID_V_sha256Identifier |
86 | | }; |
87 | | #define DER_AID_SZ_sha256Identifier sizeof(ossl_der_aid_sha256Identifier) |
88 | | |
89 | | #define DER_AID_V_sha384Identifier \ |
90 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
91 | | DER_OID_SZ_id_sha384 + DER_SZ_NULL, \ |
92 | | DER_OID_V_id_sha384, \ |
93 | | DER_V_NULL |
94 | | extern const unsigned char ossl_der_aid_sha384Identifier[]; |
95 | | const unsigned char ossl_der_aid_sha384Identifier[] = { |
96 | | DER_AID_V_sha384Identifier |
97 | | }; |
98 | | #define DER_AID_SZ_sha384Identifier sizeof(ossl_der_aid_sha384Identifier) |
99 | | |
100 | | #define DER_AID_V_sha512Identifier \ |
101 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
102 | | DER_OID_SZ_id_sha512 + DER_SZ_NULL, \ |
103 | | DER_OID_V_id_sha512, \ |
104 | | DER_V_NULL |
105 | | extern const unsigned char ossl_der_aid_sha512Identifier[]; |
106 | | const unsigned char ossl_der_aid_sha512Identifier[] = { |
107 | | DER_AID_V_sha512Identifier |
108 | | }; |
109 | | #define DER_AID_SZ_sha512Identifier sizeof(ossl_der_aid_sha512Identifier) |
110 | | |
111 | | #define DER_AID_V_sha512_224Identifier \ |
112 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
113 | | DER_OID_SZ_id_sha512_224 + DER_SZ_NULL, \ |
114 | | DER_OID_V_id_sha512_224, \ |
115 | | DER_V_NULL |
116 | | extern const unsigned char ossl_der_aid_sha512_224Identifier[]; |
117 | | const unsigned char ossl_der_aid_sha512_224Identifier[] = { |
118 | | DER_AID_V_sha512_224Identifier |
119 | | }; |
120 | | #define DER_AID_SZ_sha512_224Identifier sizeof(ossl_der_aid_sha512_224Identifier) |
121 | | |
122 | | #define DER_AID_V_sha512_256Identifier \ |
123 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
124 | | DER_OID_SZ_id_sha512_256 + DER_SZ_NULL, \ |
125 | | DER_OID_V_id_sha512_256, \ |
126 | | DER_V_NULL |
127 | | extern const unsigned char ossl_der_aid_sha512_256Identifier[]; |
128 | | const unsigned char ossl_der_aid_sha512_256Identifier[] = { |
129 | | DER_AID_V_sha512_256Identifier |
130 | | }; |
131 | | #define DER_AID_SZ_sha512_256Identifier sizeof(ossl_der_aid_sha512_256Identifier) |
132 | | |
133 | | /*- |
134 | | * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1 |
135 | | * |
136 | | * HashAlgorithm ::= AlgorithmIdentifier { |
137 | | * {OAEP-PSSDigestAlgorithms} |
138 | | * } |
139 | | * |
140 | | * ... |
141 | | * |
142 | | * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= { |
143 | | * { OID id-mgf1 PARAMETERS HashAlgorithm }, |
144 | | * ... -- Allows for future expansion -- |
145 | | * } |
146 | | */ |
147 | | |
148 | | /* |
149 | | * The names for the MGF1 AlgorithmIdentifiers are borrowed and expanded |
150 | | * from https://tools.ietf.org/html/rfc4055#section-2.1 |
151 | | * |
152 | | * mgf1SHA1Identifier AlgorithmIdentifier ::= |
153 | | * { id-mgf1, sha1Identifier } |
154 | | * mgf1SHA224Identifier AlgorithmIdentifier ::= |
155 | | * { id-mgf1, sha224Identifier } |
156 | | * mgf1SHA256Identifier AlgorithmIdentifier ::= |
157 | | * { id-mgf1, sha256Identifier } |
158 | | * mgf1SHA384Identifier AlgorithmIdentifier ::= |
159 | | * { id-mgf1, sha384Identifier } |
160 | | * mgf1SHA512Identifier AlgorithmIdentifier ::= |
161 | | * { id-mgf1, sha512Identifier } |
162 | | */ |
163 | | #if 0 /* Currently unused */ |
164 | | #define DER_AID_V_mgf1SHA1Identifier \ |
165 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
166 | | DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha1Identifier, \ |
167 | | DER_OID_V_id_mgf1, \ |
168 | | DER_AID_V_sha1Identifier |
169 | | static const unsigned char der_aid_mgf1SHA1Identifier[] = { |
170 | | DER_AID_V_mgf1SHA1Identifier |
171 | | }; |
172 | | #define DER_AID_SZ_mgf1SHA1Identifier sizeof(der_aid_mgf1SHA1Identifier) |
173 | | #endif |
174 | | |
175 | | #define DER_AID_V_mgf1SHA224Identifier \ |
176 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
177 | | DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha224Identifier, \ |
178 | | DER_OID_V_id_mgf1, \ |
179 | | DER_AID_V_sha224Identifier |
180 | | static const unsigned char der_aid_mgf1SHA224Identifier[] = { |
181 | | DER_AID_V_mgf1SHA224Identifier |
182 | | }; |
183 | | #define DER_AID_SZ_mgf1SHA224Identifier sizeof(der_aid_mgf1SHA224Identifier) |
184 | | |
185 | | #define DER_AID_V_mgf1SHA256Identifier \ |
186 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
187 | | DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha256Identifier, \ |
188 | | DER_OID_V_id_mgf1, \ |
189 | | DER_AID_V_sha256Identifier |
190 | | static const unsigned char der_aid_mgf1SHA256Identifier[] = { |
191 | | DER_AID_V_mgf1SHA256Identifier |
192 | | }; |
193 | | #define DER_AID_SZ_mgf1SHA256Identifier sizeof(der_aid_mgf1SHA256Identifier) |
194 | | |
195 | | #define DER_AID_V_mgf1SHA384Identifier \ |
196 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
197 | | DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha384Identifier, \ |
198 | | DER_OID_V_id_mgf1, \ |
199 | | DER_AID_V_sha384Identifier |
200 | | static const unsigned char der_aid_mgf1SHA384Identifier[] = { |
201 | | DER_AID_V_mgf1SHA384Identifier |
202 | | }; |
203 | | #define DER_AID_SZ_mgf1SHA384Identifier sizeof(der_aid_mgf1SHA384Identifier) |
204 | | |
205 | | #define DER_AID_V_mgf1SHA512Identifier \ |
206 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
207 | | DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512Identifier, \ |
208 | | DER_OID_V_id_mgf1, \ |
209 | | DER_AID_V_sha512Identifier |
210 | | static const unsigned char der_aid_mgf1SHA512Identifier[] = { |
211 | | DER_AID_V_mgf1SHA512Identifier |
212 | | }; |
213 | | #define DER_AID_SZ_mgf1SHA512Identifier sizeof(der_aid_mgf1SHA512Identifier) |
214 | | |
215 | | #define DER_AID_V_mgf1SHA512_224Identifier \ |
216 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
217 | | DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512_224Identifier, \ |
218 | | DER_OID_V_id_mgf1, \ |
219 | | DER_AID_V_sha512_224Identifier |
220 | | static const unsigned char der_aid_mgf1SHA512_224Identifier[] = { |
221 | | DER_AID_V_mgf1SHA512_224Identifier |
222 | | }; |
223 | | #define DER_AID_SZ_mgf1SHA512_224Identifier sizeof(der_aid_mgf1SHA512_224Identifier) |
224 | | |
225 | | #define DER_AID_V_mgf1SHA512_256Identifier \ |
226 | | DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ |
227 | | DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512_256Identifier, \ |
228 | | DER_OID_V_id_mgf1, \ |
229 | | DER_AID_V_sha512_256Identifier |
230 | | static const unsigned char der_aid_mgf1SHA512_256Identifier[] = { |
231 | | DER_AID_V_mgf1SHA512_256Identifier |
232 | | }; |
233 | | #define DER_AID_SZ_mgf1SHA512_256Identifier sizeof(der_aid_mgf1SHA512_256Identifier) |
234 | | |
235 | | |
236 | | #define MGF1_SHA_CASE(bits, var) \ |
237 | 0 | case NID_sha##bits: \ |
238 | 0 | var = der_aid_mgf1SHA##bits##Identifier; \ |
239 | 0 | var##_sz = sizeof(der_aid_mgf1SHA##bits##Identifier); \ |
240 | 0 | break; |
241 | | |
242 | | /*- |
243 | | * The name is borrowed from https://tools.ietf.org/html/rfc8017#appendix-A.2.1 |
244 | | * |
245 | | * MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} } |
246 | | */ |
247 | | static int DER_w_MaskGenAlgorithm(WPACKET *pkt, int tag, |
248 | | const RSA_PSS_PARAMS_30 *pss) |
249 | 8 | { |
250 | 8 | if (pss != NULL && ossl_rsa_pss_params_30_maskgenalg(pss) == NID_mgf1) { |
251 | 8 | int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss); |
252 | 8 | const unsigned char *maskgenalg = NULL; |
253 | 8 | size_t maskgenalg_sz = 0; |
254 | | |
255 | 8 | switch (maskgenhashalg_nid) { |
256 | 8 | case NID_sha1: |
257 | 8 | break; |
258 | 0 | MGF1_SHA_CASE(224, maskgenalg); |
259 | 0 | MGF1_SHA_CASE(256, maskgenalg); |
260 | 0 | MGF1_SHA_CASE(384, maskgenalg); |
261 | 0 | MGF1_SHA_CASE(512, maskgenalg); |
262 | 0 | MGF1_SHA_CASE(512_224, maskgenalg); |
263 | 0 | MGF1_SHA_CASE(512_256, maskgenalg); |
264 | 0 | default: |
265 | 0 | return 0; |
266 | 8 | } |
267 | | |
268 | | /* If there is none (or it was the default), we write nothing */ |
269 | 8 | if (maskgenalg == NULL) |
270 | 8 | return 1; |
271 | | |
272 | 0 | return ossl_DER_w_precompiled(pkt, tag, maskgenalg, maskgenalg_sz); |
273 | 8 | } |
274 | 0 | return 0; |
275 | 8 | } |
276 | | |
277 | | #define OAEP_PSS_MD_CASE(name, var) \ |
278 | 8 | case NID_##name: \ |
279 | 8 | var = ossl_der_aid_##name##Identifier; \ |
280 | 8 | var##_sz = sizeof(ossl_der_aid_##name##Identifier); \ |
281 | 8 | break; |
282 | | |
283 | | int ossl_DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, |
284 | | const RSA_PSS_PARAMS_30 *pss) |
285 | 8 | { |
286 | 8 | int hashalg_nid, default_hashalg_nid; |
287 | 8 | int saltlen, default_saltlen; |
288 | 8 | int trailerfield, default_trailerfield; |
289 | 8 | const unsigned char *hashalg = NULL; |
290 | 8 | size_t hashalg_sz = 0; |
291 | | |
292 | | /* |
293 | | * For an unrestricted key, this function should not have been called; |
294 | | * the caller must be in control, because unrestricted keys are permitted |
295 | | * in some situations (when encoding the public key in a SubjectKeyInfo, |
296 | | * for example) while not in others, and this function doesn't know the |
297 | | * intent. Therefore, we assert that here, the PSS parameters must show |
298 | | * that the key is restricted. |
299 | | */ |
300 | 8 | if (!ossl_assert(pss != NULL |
301 | 8 | && !ossl_rsa_pss_params_30_is_unrestricted(pss))) |
302 | 0 | return 0; |
303 | | |
304 | 8 | hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss); |
305 | 8 | saltlen = ossl_rsa_pss_params_30_saltlen(pss); |
306 | 8 | trailerfield = ossl_rsa_pss_params_30_trailerfield(pss); |
307 | | |
308 | 8 | if (saltlen < 0) { |
309 | 0 | ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH); |
310 | 0 | return 0; |
311 | 0 | } |
312 | 8 | if (trailerfield != 1) { |
313 | 0 | ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_TRAILER); |
314 | 0 | return 0; |
315 | 0 | } |
316 | | |
317 | | /* Getting default values */ |
318 | 8 | default_hashalg_nid = ossl_rsa_pss_params_30_hashalg(NULL); |
319 | 8 | default_saltlen = ossl_rsa_pss_params_30_saltlen(NULL); |
320 | 8 | default_trailerfield = ossl_rsa_pss_params_30_trailerfield(NULL); |
321 | | |
322 | | /* |
323 | | * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1: |
324 | | * |
325 | | * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { |
326 | | * { OID id-sha1 PARAMETERS NULL }| |
327 | | * { OID id-sha224 PARAMETERS NULL }| |
328 | | * { OID id-sha256 PARAMETERS NULL }| |
329 | | * { OID id-sha384 PARAMETERS NULL }| |
330 | | * { OID id-sha512 PARAMETERS NULL }| |
331 | | * { OID id-sha512-224 PARAMETERS NULL }| |
332 | | * { OID id-sha512-256 PARAMETERS NULL }, |
333 | | * ... -- Allows for future expansion -- |
334 | | * } |
335 | | */ |
336 | 8 | switch (hashalg_nid) { |
337 | 8 | OAEP_PSS_MD_CASE(sha1, hashalg); |
338 | 0 | OAEP_PSS_MD_CASE(sha224, hashalg); |
339 | 0 | OAEP_PSS_MD_CASE(sha256, hashalg); |
340 | 0 | OAEP_PSS_MD_CASE(sha384, hashalg); |
341 | 0 | OAEP_PSS_MD_CASE(sha512, hashalg); |
342 | 0 | OAEP_PSS_MD_CASE(sha512_224, hashalg); |
343 | 0 | OAEP_PSS_MD_CASE(sha512_256, hashalg); |
344 | 0 | default: |
345 | 0 | return 0; |
346 | 8 | } |
347 | | |
348 | 8 | return ossl_DER_w_begin_sequence(pkt, tag) |
349 | 8 | && (trailerfield == default_trailerfield |
350 | 8 | || ossl_DER_w_uint32(pkt, 3, (uint32_t)trailerfield)) |
351 | 8 | && (saltlen == default_saltlen || ossl_DER_w_uint32(pkt, 2, (uint32_t)saltlen)) |
352 | 8 | && DER_w_MaskGenAlgorithm(pkt, 1, pss) |
353 | 8 | && (hashalg_nid == default_hashalg_nid |
354 | 8 | || ossl_DER_w_precompiled(pkt, 0, hashalg, hashalg_sz)) |
355 | 8 | && ossl_DER_w_end_sequence(pkt, tag); |
356 | 8 | } |
357 | | |
358 | | /* Aliases so we can have a uniform RSA_CASE */ |
359 | 0 | #define ossl_der_oid_rsassaPss ossl_der_oid_id_RSASSA_PSS |
360 | | |
361 | | #define RSA_CASE(name, var) \ |
362 | 0 | var##_nid = NID_##name; \ |
363 | 0 | var##_oid = ossl_der_oid_##name; \ |
364 | 0 | var##_oid_sz = sizeof(ossl_der_oid_##name); \ |
365 | 0 | break; |
366 | | |
367 | | int ossl_DER_w_algorithmIdentifier_RSA_PSS(WPACKET *pkt, int tag, |
368 | | int rsa_type, |
369 | | const RSA_PSS_PARAMS_30 *pss) |
370 | 0 | { |
371 | 0 | int rsa_nid = NID_undef; |
372 | 0 | const unsigned char *rsa_oid = NULL; |
373 | 0 | size_t rsa_oid_sz = 0; |
374 | |
|
375 | 0 | switch (rsa_type) { |
376 | 0 | case RSA_FLAG_TYPE_RSA: |
377 | 0 | RSA_CASE(rsaEncryption, rsa); |
378 | 0 | case RSA_FLAG_TYPE_RSASSAPSS: |
379 | 0 | RSA_CASE(rsassaPss, rsa); |
380 | 0 | } |
381 | | |
382 | 0 | if (rsa_oid == NULL) |
383 | 0 | return 0; |
384 | | |
385 | 0 | return ossl_DER_w_begin_sequence(pkt, tag) |
386 | 0 | && (rsa_nid != NID_rsassaPss |
387 | 0 | || ossl_rsa_pss_params_30_is_unrestricted(pss) |
388 | 0 | || ossl_DER_w_RSASSA_PSS_params(pkt, -1, pss)) |
389 | 0 | && ossl_DER_w_precompiled(pkt, -1, rsa_oid, rsa_oid_sz) |
390 | 0 | && ossl_DER_w_end_sequence(pkt, tag); |
391 | 0 | } |
392 | | |
393 | | int ossl_DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa) |
394 | 0 | { |
395 | 0 | int rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK); |
396 | 0 | RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa); |
397 | |
|
398 | 0 | return ossl_DER_w_algorithmIdentifier_RSA_PSS(pkt, tag, rsa_type, |
399 | 0 | pss_params); |
400 | 0 | } |