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