OpenCoverage

rsa_oaep.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/rsa/rsa_oaep.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.-
3 *-
4 * Licensed under the OpenSSL license (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/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */-
11-
12/*-
13 * See Victor Shoup, "OAEP reconsidered," Nov. 2000, <URL:-
14 * http://www.shoup.net/papers/oaep.ps.Z> for problems with the security-
15 * proof for the original OAEP scheme, which EME-OAEP is based on. A new-
16 * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern,-
17 * "RSA-OEAP is Still Alive!", Dec. 2000, <URL:-
18 * http://eprint.iacr.org/2000/061/>. The new proof has stronger requirements-
19 * for the underlying permutation: "partial-one-wayness" instead of-
20 * one-wayness. For the RSA function, this is an equivalent notion.-
21 */-
22-
23#include "internal/constant_time_locl.h"-
24-
25#include <stdio.h>-
26#include "internal/cryptlib.h"-
27#include <openssl/bn.h>-
28#include <openssl/evp.h>-
29#include <openssl/rand.h>-
30#include <openssl/sha.h>-
31#include "rsa_locl.h"-
32-
33int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,-
34 const unsigned char *from, int flen,-
35 const unsigned char *param, int plen)-
36{-
37 return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen,
executed 3 times by 1 test: return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, param, plen, ((void *)0) , ((void *)0) );
Executed by:
  • libcrypto.so.1.1
3
38 param, plen, NULL, NULL);
executed 3 times by 1 test: return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, param, plen, ((void *)0) , ((void *)0) );
Executed by:
  • libcrypto.so.1.1
3
39}-
40-
41int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,-
42 const unsigned char *from, int flen,-
43 const unsigned char *param, int plen,-
44 const EVP_MD *md, const EVP_MD *mgf1md)-
45{-
46 int rv = 0;-
47 int i, emlen = tlen - 1;-
48 unsigned char *db, *seed;-
49 unsigned char *dbmask = NULL;-
50 unsigned char seedmask[EVP_MAX_MD_SIZE];-
51 int mdlen, dbmask_len = 0;-
52-
53 if (md == NULL)
md == ((void *)0)Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 2 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
2-3
54 md = EVP_sha1();
executed 3 times by 1 test: md = EVP_sha1();
Executed by:
  • libcrypto.so.1.1
3
55 if (mgf1md == NULL)
mgf1md == ((void *)0)Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-5
56 mgf1md = md;
executed 5 times by 1 test: mgf1md = md;
Executed by:
  • libcrypto.so.1.1
5
57-
58 mdlen = EVP_MD_size(md);-
59-
60 if (flen > emlen - 2 * mdlen - 1) {
flen > emlen - 2 * mdlen - 1Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-5
61 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,-
62 RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);-
63 return 0;
never executed: return 0;
0
64 }-
65-
66 if (emlen < 2 * mdlen + 1) {
emlen < 2 * mdlen + 1Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-5
67 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,-
68 RSA_R_KEY_SIZE_TOO_SMALL);-
69 return 0;
never executed: return 0;
0
70 }-
71-
72 to[0] = 0;-
73 seed = to + 1;-
74 db = to + mdlen + 1;-
75-
76 if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
!EVP_Digest((v... ((void *)0) )Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-5
77 goto err;
never executed: goto err;
0
78 memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);-
79 db[emlen - flen - mdlen - 1] = 0x01;-
80 memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);-
81 if (RAND_bytes(seed, mdlen) <= 0)
RAND_bytes(seed, mdlen) <= 0Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-5
82 goto err;
never executed: goto err;
0
83-
84 dbmask_len = emlen - mdlen;-
85 dbmask = OPENSSL_malloc(dbmask_len);-
86 if (dbmask == NULL) {
dbmask == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-5
87 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);-
88 goto err;
never executed: goto err;
0
89 }-
90-
91 if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0)
PKCS1_MGF1(dbm...n, mgf1md) < 0Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-5
92 goto err;
never executed: goto err;
0
93 for (i = 0; i < dbmask_len; i++)
i < dbmask_lenDescription
TRUEevaluated 637 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
5-637
94 db[i] ^= dbmask[i];
executed 637 times by 1 test: db[i] ^= dbmask[i];
Executed by:
  • libcrypto.so.1.1
637
95-
96 if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0)
PKCS1_MGF1(see...n, mgf1md) < 0Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-5
97 goto err;
never executed: goto err;
0
98 for (i = 0; i < mdlen; i++)
i < mdlenDescription
TRUEevaluated 112 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
5-112
99 seed[i] ^= seedmask[i];
executed 112 times by 1 test: seed[i] ^= seedmask[i];
Executed by:
  • libcrypto.so.1.1
112
100 rv = 1;-
101-
102 err:
code before this statement executed 5 times by 1 test: err:
Executed by:
  • libcrypto.so.1.1
5
103 OPENSSL_cleanse(seedmask, sizeof(seedmask));-
104 OPENSSL_clear_free(dbmask, dbmask_len);-
105 return rv;
executed 5 times by 1 test: return rv;
Executed by:
  • libcrypto.so.1.1
5
106}-
107-
108int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,-
109 const unsigned char *from, int flen, int num,-
110 const unsigned char *param, int plen)-
111{-
112 return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num,
executed 490 times by 1 test: return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num, param, plen, ((void *)0) , ((void *)0) );
Executed by:
  • libcrypto.so.1.1
490
113 param, plen, NULL, NULL);
executed 490 times by 1 test: return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num, param, plen, ((void *)0) , ((void *)0) );
Executed by:
  • libcrypto.so.1.1
490
114}-
115-
116int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,-
117 const unsigned char *from, int flen,-
118 int num, const unsigned char *param,-
119 int plen, const EVP_MD *md,-
120 const EVP_MD *mgf1md)-
121{-
122 int i, dblen = 0, mlen = -1, one_index = 0, msg_index;-
123 unsigned int good, found_one_byte;-
124 const unsigned char *maskedseed, *maskeddb;-
125 /*-
126 * |em| is the encoded message, zero-padded to exactly |num| bytes: em =-
127 * Y || maskedSeed || maskedDB-
128 */-
129 unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE],-
130 phash[EVP_MAX_MD_SIZE];-
131 int mdlen;-
132-
133 if (md == NULL)
md == ((void *)0)Description
TRUEevaluated 490 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 64 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
64-490
134 md = EVP_sha1();
executed 490 times by 1 test: md = EVP_sha1();
Executed by:
  • libcrypto.so.1.1
490
135 if (mgf1md == NULL)
mgf1md == ((void *)0)Description
TRUEevaluated 492 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 62 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
62-492
136 mgf1md = md;
executed 492 times by 1 test: mgf1md = md;
Executed by:
  • libcrypto.so.1.1
492
137-
138 mdlen = EVP_MD_size(md);-
139-
140 if (tlen <= 0 || flen <= 0)
tlen <= 0Description
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
flen <= 0Description
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-554
141 return -1;
never executed: return -1;
0
142 /*-
143 * |num| is the length of the modulus; |flen| is the length of the-
144 * encoded message. Therefore, for any |from| that was obtained by-
145 * decrypting a ciphertext, we must have |flen| <= |num|. Similarly,-
146 * num < 2 * mdlen + 2 must hold for the modulus irrespective of-
147 * the ciphertext, see PKCS #1 v2.2, section 7.1.2.-
148 * This does not leak any side-channel information.-
149 */-
150 if (num < flen || num < 2 * mdlen + 2)
num < flenDescription
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
num < 2 * mdlen + 2Description
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-554
151 goto decoding_err;
never executed: goto decoding_err;
0
152-
153 dblen = num - mdlen - 1;-
154 db = OPENSSL_malloc(dblen);-
155 if (db == NULL) {
db == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-554
156 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);-
157 goto cleanup;
never executed: goto cleanup;
0
158 }-
159-
160 if (flen != num) {
flen != numDescription
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-554
161 em = OPENSSL_zalloc(num);-
162 if (em == NULL) {
em == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
163 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1,-
164 ERR_R_MALLOC_FAILURE);-
165 goto cleanup;
never executed: goto cleanup;
0
166 }-
167-
168 /*-
169 * Caller is encouraged to pass zero-padded message created with-
170 * BN_bn2binpad, but if it doesn't, we do this zero-padding copy-
171 * to avoid leaking that information. The copy still leaks some-
172 * side-channel information, but it's impossible to have a fixed-
173 * memory access pattern since we can't read out of the bounds of-
174 * |from|.-
175 */-
176 memcpy(em + num - flen, from, flen);-
177 from = em;-
178 }
never executed: end of block
0
179-
180 /*-
181 * The first byte must be zero, however we must not leak if this is-
182 * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA-
183 * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).-
184 */-
185 good = constant_time_is_zero(from[0]);-
186-
187 maskedseed = from + 1;-
188 maskeddb = from + 1 + mdlen;-
189-
190 if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
PKCS1_MGF1(see...dblen, mgf1md)Description
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-554
191 goto cleanup;
never executed: goto cleanup;
0
192 for (i = 0; i < mdlen; i++)
i < mdlenDescription
TRUEevaluated 11092 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
554-11092
193 seed[i] ^= maskedseed[i];
executed 11092 times by 1 test: seed[i] ^= maskedseed[i];
Executed by:
  • libcrypto.so.1.1
11092
194-
195 if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md))
PKCS1_MGF1(db,...mdlen, mgf1md)Description
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-554
196 goto cleanup;
never executed: goto cleanup;
0
197 for (i = 0; i < dblen; i++)
i < dblenDescription
TRUEevaluated 44696 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
554-44696
198 db[i] ^= maskeddb[i];
executed 44696 times by 1 test: db[i] ^= maskeddb[i];
Executed by:
  • libcrypto.so.1.1
44696
199-
200 if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
!EVP_Digest((v... ((void *)0) )Description
TRUEnever evaluated
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-554
201 goto cleanup;
never executed: goto cleanup;
0
202-
203 good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));-
204-
205 found_one_byte = 0;-
206 for (i = mdlen; i < dblen; i++) {
i < dblenDescription
TRUEevaluated 33604 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 554 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
554-33604
207 /*-
208 * Padding consists of a number of 0-bytes, followed by a 1.-
209 */-
210 unsigned int equals1 = constant_time_eq(db[i], 1);-
211 unsigned int equals0 = constant_time_is_zero(db[i]);-
212 one_index = constant_time_select_int(~found_one_byte & equals1,-
213 i, one_index);-
214 found_one_byte |= equals1;-
215 good &= (found_one_byte | equals0);-
216 }
executed 33604 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
33604
217-
218 good &= found_one_byte;-
219-
220 /*-
221 * At this point |good| is zero unless the plaintext was valid,-
222 * so plaintext-awareness ensures timing side-channels are no longer a-
223 * concern.-
224 */-
225 if (!good)
!goodDescription
TRUEevaluated 485 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 69 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
69-485
226 goto decoding_err;
executed 485 times by 1 test: goto decoding_err;
Executed by:
  • libcrypto.so.1.1
485
227-
228 msg_index = one_index + 1;-
229 mlen = dblen - msg_index;-
230-
231 if (tlen < mlen) {
tlen < mlenDescription
TRUEnever evaluated
FALSEevaluated 69 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-69
232 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE);-
233 mlen = -1;-
234 } else {
never executed: end of block
0
235 memcpy(to, db + msg_index, mlen);-
236 goto cleanup;
executed 69 times by 1 test: goto cleanup;
Executed by:
  • libcrypto.so.1.1
69
237 }-
238-
239 decoding_err:
code before this statement never executed: decoding_err:
0
240 /*-
241 * To avoid chosen ciphertext attacks, the error message should not-
242 * reveal which kind of decoding error happened.-
243 */-
244 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1,-
245 RSA_R_OAEP_DECODING_ERROR);-
246 cleanup:
code before this statement executed 485 times by 1 test: cleanup:
Executed by:
  • libcrypto.so.1.1
485
247 OPENSSL_cleanse(seed, sizeof(seed));-
248 OPENSSL_clear_free(db, dblen);-
249 OPENSSL_clear_free(em, num);-
250 return mlen;
executed 554 times by 1 test: return mlen;
Executed by:
  • libcrypto.so.1.1
554
251}-
252-
253int PKCS1_MGF1(unsigned char *mask, long len,-
254 const unsigned char *seed, long seedlen, const EVP_MD *dgst)-
255{-
256 long i, outlen = 0;-
257 unsigned char cnt[4];-
258 EVP_MD_CTX *c = EVP_MD_CTX_new();-
259 unsigned char md[EVP_MAX_MD_SIZE];-
260 int mdlen;-
261 int rv = -1;-
262-
263 if (c == NULL)
c == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 3210 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-3210
264 goto err;
never executed: goto err;
0
265 mdlen = EVP_MD_size(dgst);-
266 if (mdlen < 0)
mdlen < 0Description
TRUEnever evaluated
FALSEevaluated 3210 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-3210
267 goto err;
never executed: goto err;
0
268 for (i = 0; outlen < len; i++) {
outlen < lenDescription
TRUEevaluated 17739 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 3210 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
3210-17739
269 cnt[0] = (unsigned char)((i >> 24) & 255);-
270 cnt[1] = (unsigned char)((i >> 16) & 255);-
271 cnt[2] = (unsigned char)((i >> 8)) & 255;-
272 cnt[3] = (unsigned char)(i & 255);-
273 if (!EVP_DigestInit_ex(c, dgst, NULL)
!EVP_DigestIni... ((void *)0) )Description
TRUEnever evaluated
FALSEevaluated 17739 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-17739
274 || !EVP_DigestUpdate(c, seed, seedlen)
!EVP_DigestUpd...seed, seedlen)Description
TRUEnever evaluated
FALSEevaluated 17739 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-17739
275 || !EVP_DigestUpdate(c, cnt, 4))
!EVP_DigestUpdate(c, cnt, 4)Description
TRUEnever evaluated
FALSEevaluated 17739 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-17739
276 goto err;
never executed: goto err;
0
277 if (outlen + mdlen <= len) {
outlen + mdlen <= lenDescription
TRUEevaluated 15090 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 2649 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
2649-15090
278 if (!EVP_DigestFinal_ex(c, mask + outlen, NULL))
!EVP_DigestFin... ((void *)0) )Description
TRUEnever evaluated
FALSEevaluated 15090 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-15090
279 goto err;
never executed: goto err;
0
280 outlen += mdlen;-
281 } else {
executed 15090 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
15090
282 if (!EVP_DigestFinal_ex(c, md, NULL))
!EVP_DigestFin... ((void *)0) )Description
TRUEnever evaluated
FALSEevaluated 2649 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-2649
283 goto err;
never executed: goto err;
0
284 memcpy(mask + outlen, md, len - outlen);-
285 outlen = len;-
286 }
executed 2649 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
2649
287 }-
288 rv = 0;-
289 err:
code before this statement executed 3210 times by 1 test: err:
Executed by:
  • libcrypto.so.1.1
3210
290 OPENSSL_cleanse(md, sizeof(md));-
291 EVP_MD_CTX_free(c);-
292 return rv;
executed 3210 times by 1 test: return rv;
Executed by:
  • libcrypto.so.1.1
3210
293}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2