Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/libressl/src/crypto/rsa/rsa_oaep.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* $OpenBSD: rsa_oaep.c,v 1.29 2018/08/19 20:17:20 tb Exp $ */ | - | ||||||||||||
2 | /* Written by Ulf Moeller. This software is distributed on an "AS IS" | - | ||||||||||||
3 | basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */ | - | ||||||||||||
4 | - | |||||||||||||
5 | /* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ | - | ||||||||||||
6 | - | |||||||||||||
7 | /* See Victor Shoup, "OAEP reconsidered," Nov. 2000, | - | ||||||||||||
8 | * <URL: http://www.shoup.net/papers/oaep.ps.Z> | - | ||||||||||||
9 | * for problems with the security proof for the | - | ||||||||||||
10 | * original OAEP scheme, which EME-OAEP is based on. | - | ||||||||||||
11 | * | - | ||||||||||||
12 | * A new proof can be found in E. Fujisaki, T. Okamoto, | - | ||||||||||||
13 | * D. Pointcheval, J. Stern, "RSA-OEAP is Still Alive!", | - | ||||||||||||
14 | * Dec. 2000, <URL: http://eprint.iacr.org/2000/061/>. | - | ||||||||||||
15 | * The new proof has stronger requirements for the | - | ||||||||||||
16 | * underlying permutation: "partial-one-wayness" instead | - | ||||||||||||
17 | * of one-wayness. For the RSA function, this is | - | ||||||||||||
18 | * an equivalent notion. | - | ||||||||||||
19 | */ | - | ||||||||||||
20 | - | |||||||||||||
21 | #include <stdio.h> | - | ||||||||||||
22 | #include <stdlib.h> | - | ||||||||||||
23 | #include <string.h> | - | ||||||||||||
24 | - | |||||||||||||
25 | #include <openssl/opensslconf.h> | - | ||||||||||||
26 | - | |||||||||||||
27 | #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) | - | ||||||||||||
28 | - | |||||||||||||
29 | #include <openssl/bn.h> | - | ||||||||||||
30 | #include <openssl/err.h> | - | ||||||||||||
31 | #include <openssl/evp.h> | - | ||||||||||||
32 | #include <openssl/rsa.h> | - | ||||||||||||
33 | #include <openssl/sha.h> | - | ||||||||||||
34 | - | |||||||||||||
35 | static int MGF1(unsigned char *mask, long len, const unsigned char *seed, | - | ||||||||||||
36 | long seedlen); | - | ||||||||||||
37 | - | |||||||||||||
38 | int | - | ||||||||||||
39 | RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, | - | ||||||||||||
40 | const unsigned char *from, int flen, const unsigned char *param, int plen) | - | ||||||||||||
41 | { | - | ||||||||||||
42 | int i, emlen = tlen - 1; | - | ||||||||||||
43 | unsigned char *db, *seed; | - | ||||||||||||
44 | unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH]; | - | ||||||||||||
45 | - | |||||||||||||
46 | if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1) {
| 0-3 | ||||||||||||
47 | RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); | - | ||||||||||||
48 | return 0; never executed: return 0; | 0 | ||||||||||||
49 | } | - | ||||||||||||
50 | - | |||||||||||||
51 | if (emlen < 2 * SHA_DIGEST_LENGTH + 1) {
| 0-3 | ||||||||||||
52 | RSAerror(RSA_R_KEY_SIZE_TOO_SMALL); | - | ||||||||||||
53 | return 0; never executed: return 0; | 0 | ||||||||||||
54 | } | - | ||||||||||||
55 | - | |||||||||||||
56 | to[0] = 0; | - | ||||||||||||
57 | seed = to + 1; | - | ||||||||||||
58 | db = to + SHA_DIGEST_LENGTH + 1; | - | ||||||||||||
59 | - | |||||||||||||
60 | if (!EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL))
| 0-3 | ||||||||||||
61 | return 0; never executed: return 0; | 0 | ||||||||||||
62 | memset(db + SHA_DIGEST_LENGTH, 0, | - | ||||||||||||
63 | emlen - flen - 2 * SHA_DIGEST_LENGTH - 1); | - | ||||||||||||
64 | db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01; | - | ||||||||||||
65 | memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, flen); | - | ||||||||||||
66 | arc4random_buf(seed, SHA_DIGEST_LENGTH); | - | ||||||||||||
67 | - | |||||||||||||
68 | dbmask = malloc(emlen - SHA_DIGEST_LENGTH); | - | ||||||||||||
69 | if (dbmask == NULL) {
| 0-3 | ||||||||||||
70 | RSAerror(ERR_R_MALLOC_FAILURE); | - | ||||||||||||
71 | return 0; never executed: return 0; | 0 | ||||||||||||
72 | } | - | ||||||||||||
73 | - | |||||||||||||
74 | if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed,
| 0-3 | ||||||||||||
75 | SHA_DIGEST_LENGTH) < 0) {
| 0-3 | ||||||||||||
76 | free(dbmask); | - | ||||||||||||
77 | return 0; never executed: return 0; | 0 | ||||||||||||
78 | } | - | ||||||||||||
79 | for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
| 3-179 | ||||||||||||
80 | db[i] ^= dbmask[i]; executed 179 times by 1 test: db[i] ^= dbmask[i]; Executed by:
| 179 | ||||||||||||
81 | - | |||||||||||||
82 | if (MGF1(seedmask, SHA_DIGEST_LENGTH, db,
| 0-3 | ||||||||||||
83 | emlen - SHA_DIGEST_LENGTH) < 0) {
| 0-3 | ||||||||||||
84 | free(dbmask); | - | ||||||||||||
85 | return 0; never executed: return 0; | 0 | ||||||||||||
86 | } | - | ||||||||||||
87 | for (i = 0; i < SHA_DIGEST_LENGTH; i++)
| 3-60 | ||||||||||||
88 | seed[i] ^= seedmask[i]; executed 60 times by 1 test: seed[i] ^= seedmask[i]; Executed by:
| 60 | ||||||||||||
89 | - | |||||||||||||
90 | free(dbmask); | - | ||||||||||||
91 | return 1; executed 3 times by 1 test: return 1; Executed by:
| 3 | ||||||||||||
92 | } | - | ||||||||||||
93 | - | |||||||||||||
94 | int | - | ||||||||||||
95 | RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, | - | ||||||||||||
96 | const unsigned char *from, int flen, int num, const unsigned char *param, | - | ||||||||||||
97 | int plen) | - | ||||||||||||
98 | { | - | ||||||||||||
99 | int i, dblen, mlen = -1; | - | ||||||||||||
100 | const unsigned char *maskeddb; | - | ||||||||||||
101 | int lzero; | - | ||||||||||||
102 | unsigned char *db = NULL; | - | ||||||||||||
103 | unsigned char seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH]; | - | ||||||||||||
104 | unsigned char *padded_from; | - | ||||||||||||
105 | int bad = 0; | - | ||||||||||||
106 | - | |||||||||||||
107 | if (--num < 2 * SHA_DIGEST_LENGTH + 1)
| 0-490 | ||||||||||||
108 | /* | - | ||||||||||||
109 | * 'num' is the length of the modulus, i.e. does not depend | - | ||||||||||||
110 | * on the particular ciphertext. | - | ||||||||||||
111 | */ | - | ||||||||||||
112 | goto decoding_err; never executed: goto decoding_err; | 0 | ||||||||||||
113 | - | |||||||||||||
114 | lzero = num - flen; | - | ||||||||||||
115 | if (lzero < 0) {
| 10-480 | ||||||||||||
116 | /* | - | ||||||||||||
117 | * signalling this error immediately after detection might allow | - | ||||||||||||
118 | * for side-channel attacks (e.g. timing if 'plen' is huge | - | ||||||||||||
119 | * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA | - | ||||||||||||
120 | * Optimal Asymmetric Encryption Padding (OAEP) [...]", | - | ||||||||||||
121 | * CRYPTO 2001), so we use a 'bad' flag | - | ||||||||||||
122 | */ | - | ||||||||||||
123 | bad = 1; | - | ||||||||||||
124 | lzero = 0; | - | ||||||||||||
125 | flen = num; /* don't overflow the memcpy to padded_from */ | - | ||||||||||||
126 | } executed 480 times by 1 test: end of block Executed by:
| 480 | ||||||||||||
127 | - | |||||||||||||
128 | dblen = num - SHA_DIGEST_LENGTH; | - | ||||||||||||
129 | if ((db = malloc(dblen + num)) == NULL) {
| 0-490 | ||||||||||||
130 | RSAerror(ERR_R_MALLOC_FAILURE); | - | ||||||||||||
131 | return -1; never executed: return -1; | 0 | ||||||||||||
132 | } | - | ||||||||||||
133 | - | |||||||||||||
134 | /* | - | ||||||||||||
135 | * Always do this zero-padding copy (even when lzero == 0) | - | ||||||||||||
136 | * to avoid leaking timing info about the value of lzero. | - | ||||||||||||
137 | */ | - | ||||||||||||
138 | padded_from = db + dblen; | - | ||||||||||||
139 | memset(padded_from, 0, lzero); | - | ||||||||||||
140 | memcpy(padded_from + lzero, from, flen); | - | ||||||||||||
141 | - | |||||||||||||
142 | maskeddb = padded_from + SHA_DIGEST_LENGTH; | - | ||||||||||||
143 | - | |||||||||||||
144 | if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
| 0-490 | ||||||||||||
145 | goto err; never executed: goto err; | 0 | ||||||||||||
146 | for (i = 0; i < SHA_DIGEST_LENGTH; i++)
| 490-9800 | ||||||||||||
147 | seed[i] ^= padded_from[i]; executed 9800 times by 1 test: seed[i] ^= padded_from[i]; Executed by:
| 9800 | ||||||||||||
148 | - | |||||||||||||
149 | if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
| 0-490 | ||||||||||||
150 | goto err; never executed: goto err; | 0 | ||||||||||||
151 | for (i = 0; i < dblen; i++)
| 490-36154 | ||||||||||||
152 | db[i] ^= maskeddb[i]; executed 36154 times by 1 test: db[i] ^= maskeddb[i]; Executed by:
| 36154 | ||||||||||||
153 | - | |||||||||||||
154 | if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
| 0-490 | ||||||||||||
155 | goto err; never executed: goto err; | 0 | ||||||||||||
156 | - | |||||||||||||
157 | if (timingsafe_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
| 0-484 | ||||||||||||
158 | goto decoding_err; executed 484 times by 1 test: goto decoding_err; Executed by:
| 484 | ||||||||||||
159 | else { | - | ||||||||||||
160 | for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
| 0-190 | ||||||||||||
161 | if (db[i] != 0x00)
| 6-184 | ||||||||||||
162 | break; executed 6 times by 1 test: break; Executed by:
| 6 | ||||||||||||
163 | if (i == dblen || db[i] != 0x01)
| 0-6 | ||||||||||||
164 | goto decoding_err; never executed: goto decoding_err; | 0 | ||||||||||||
165 | else { | - | ||||||||||||
166 | /* everything looks OK */ | - | ||||||||||||
167 | - | |||||||||||||
168 | mlen = dblen - ++i; | - | ||||||||||||
169 | if (tlen < mlen) {
| 0-6 | ||||||||||||
170 | RSAerror(RSA_R_DATA_TOO_LARGE); | - | ||||||||||||
171 | mlen = -1; | - | ||||||||||||
172 | } else never executed: end of block | 0 | ||||||||||||
173 | memcpy(to, db + i, mlen); executed 6 times by 1 test: memcpy(to, db + i, mlen); Executed by:
| 6 | ||||||||||||
174 | } | - | ||||||||||||
175 | } | - | ||||||||||||
176 | free(db); | - | ||||||||||||
177 | return mlen; executed 6 times by 1 test: return mlen; Executed by:
| 6 | ||||||||||||
178 | - | |||||||||||||
179 | decoding_err: | - | ||||||||||||
180 | /* | - | ||||||||||||
181 | * To avoid chosen ciphertext attacks, the error message should not | - | ||||||||||||
182 | * reveal which kind of decoding error happened | - | ||||||||||||
183 | */ | - | ||||||||||||
184 | RSAerror(RSA_R_OAEP_DECODING_ERROR); | - | ||||||||||||
185 | err: code before this statement executed 484 times by 1 test: err: Executed by:
| 484 | ||||||||||||
186 | free(db); | - | ||||||||||||
187 | return -1; executed 484 times by 1 test: return -1; Executed by:
| 484 | ||||||||||||
188 | } | - | ||||||||||||
189 | - | |||||||||||||
190 | int | - | ||||||||||||
191 | PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, | - | ||||||||||||
192 | long seedlen, const EVP_MD *dgst) | - | ||||||||||||
193 | { | - | ||||||||||||
194 | long i, outlen = 0; | - | ||||||||||||
195 | unsigned char cnt[4]; | - | ||||||||||||
196 | EVP_MD_CTX c; | - | ||||||||||||
197 | unsigned char md[EVP_MAX_MD_SIZE]; | - | ||||||||||||
198 | int mdlen; | - | ||||||||||||
199 | int rv = -1; | - | ||||||||||||
200 | - | |||||||||||||
201 | EVP_MD_CTX_init(&c); | - | ||||||||||||
202 | mdlen = EVP_MD_size(dgst); | - | ||||||||||||
203 | if (mdlen < 0)
| 0-986 | ||||||||||||
204 | goto err; never executed: goto err; | 0 | ||||||||||||
205 | for (i = 0; outlen < len; i++) {
| 986-2646 | ||||||||||||
206 | cnt[0] = (unsigned char)((i >> 24) & 255); | - | ||||||||||||
207 | cnt[1] = (unsigned char)((i >> 16) & 255); | - | ||||||||||||
208 | cnt[2] = (unsigned char)((i >> 8)) & 255; | - | ||||||||||||
209 | cnt[3] = (unsigned char)(i & 255); | - | ||||||||||||
210 | if (!EVP_DigestInit_ex(&c, dgst, NULL) ||
| 0-2646 | ||||||||||||
211 | !EVP_DigestUpdate(&c, seed, seedlen) ||
| 0-2646 | ||||||||||||
212 | !EVP_DigestUpdate(&c, cnt, 4))
| 0-2646 | ||||||||||||
213 | goto err; never executed: goto err; | 0 | ||||||||||||
214 | if (outlen + mdlen <= len) {
| 493-2153 | ||||||||||||
215 | if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
| 0-2153 | ||||||||||||
216 | goto err; never executed: goto err; | 0 | ||||||||||||
217 | outlen += mdlen; | - | ||||||||||||
218 | } else { executed 2153 times by 1 test: end of block Executed by:
| 2153 | ||||||||||||
219 | if (!EVP_DigestFinal_ex(&c, md, NULL))
| 0-493 | ||||||||||||
220 | goto err; never executed: goto err; | 0 | ||||||||||||
221 | memcpy(mask + outlen, md, len - outlen); | - | ||||||||||||
222 | outlen = len; | - | ||||||||||||
223 | } executed 493 times by 1 test: end of block Executed by:
| 493 | ||||||||||||
224 | } | - | ||||||||||||
225 | rv = 0; | - | ||||||||||||
226 | err: code before this statement executed 986 times by 1 test: err: Executed by:
| 986 | ||||||||||||
227 | EVP_MD_CTX_cleanup(&c); | - | ||||||||||||
228 | return rv; executed 986 times by 1 test: return rv; Executed by:
| 986 | ||||||||||||
229 | } | - | ||||||||||||
230 | - | |||||||||||||
231 | static int | - | ||||||||||||
232 | MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen) | - | ||||||||||||
233 | { | - | ||||||||||||
234 | return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1()); executed 986 times by 1 test: return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1()); Executed by:
| 986 | ||||||||||||
235 | } | - | ||||||||||||
236 | #endif | - | ||||||||||||
Source code | Switch to Preprocessed file |