| 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 |