LCOV - code coverage report
Current view: top level - rsa - rsa_oaep.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 93 103 90.3 %
Date: 2014-08-02 Functions: 5 5 100.0 %
Branches: 49 74 66.2 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/rsa/rsa_oaep.c */
       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                 :            : #define OPENSSL_FIPSAPI
      22                 :            : 
      23                 :            : 
      24                 :            : #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
      25                 :            : #include <stdio.h>
      26                 :            : #include "cryptlib.h"
      27                 :            : #include <openssl/bn.h>
      28                 :            : #include <openssl/rsa.h>
      29                 :            : #include <openssl/evp.h>
      30                 :            : #include <openssl/rand.h>
      31                 :            : #include <openssl/sha.h>
      32                 :            : 
      33                 :          6 : int 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                 :          6 :         return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen,
      38                 :            :                                                 param, plen, NULL, NULL);
      39                 :            :         }
      40                 :            : 
      41                 :          8 : int 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                 :          8 :         int i, emlen = tlen - 1;
      47                 :            :         unsigned char *db, *seed;
      48                 :            :         unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE];
      49                 :            :         int mdlen;
      50                 :            : 
      51         [ +  + ]:          8 :         if (md == NULL)
      52                 :          6 :                 md = EVP_sha1();
      53         [ +  - ]:          8 :         if (mgf1md == NULL)
      54                 :          8 :                 mgf1md = md;
      55                 :            : 
      56                 :          8 :         mdlen = EVP_MD_size(md);
      57                 :            : 
      58         [ -  + ]:          8 :         if (flen > emlen - 2 * mdlen - 1)
      59                 :            :                 {
      60                 :          0 :                 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
      61                 :            :                    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
      62                 :          0 :                 return 0;
      63                 :            :                 }
      64                 :            : 
      65         [ -  + ]:          8 :         if (emlen < 2 * mdlen + 1)
      66                 :            :                 {
      67                 :          0 :                 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, RSA_R_KEY_SIZE_TOO_SMALL);
      68                 :          0 :                 return 0;
      69                 :            :                 }
      70                 :            : 
      71                 :          8 :         to[0] = 0;
      72                 :          8 :         seed = to + 1;
      73                 :          8 :         db = to + mdlen + 1;
      74                 :            : 
      75         [ +  - ]:          8 :         if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
      76                 :            :                 return 0;
      77                 :          8 :         memset(db + mdlen, 0,
      78                 :          8 :                 emlen - flen - 2 * mdlen - 1);
      79                 :          8 :         db[emlen - flen - mdlen - 1] = 0x01;
      80                 :          8 :         memcpy(db + emlen - flen - mdlen, from, (unsigned int) flen);
      81         [ +  - ]:          8 :         if (RAND_bytes(seed, mdlen) <= 0)
      82                 :            :                 return 0;
      83                 :            : #ifdef PKCS_TESTVECT
      84                 :            :         memcpy(seed,
      85                 :            :            "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
      86                 :            :            20);
      87                 :            : #endif
      88                 :            : 
      89                 :          8 :         dbmask = OPENSSL_malloc(emlen - mdlen);
      90         [ -  + ]:          8 :         if (dbmask == NULL)
      91                 :            :                 {
      92                 :          0 :                 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
      93                 :          0 :                 return 0;
      94                 :            :                 }
      95                 :            : 
      96         [ +  - ]:          8 :         if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
      97                 :            :                 return 0;
      98         [ +  + ]:        824 :         for (i = 0; i < emlen - mdlen; i++)
      99                 :        816 :                 db[i] ^= dbmask[i];
     100                 :            : 
     101         [ +  - ]:          8 :         if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
     102                 :            :                 return 0;
     103         [ +  + ]:        180 :         for (i = 0; i < mdlen; i++)
     104                 :        172 :                 seed[i] ^= seedmask[i];
     105                 :            : 
     106                 :          8 :         OPENSSL_free(dbmask);
     107                 :          8 :         return 1;
     108                 :            :         }
     109                 :            : 
     110                 :         18 : int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
     111                 :            :         const unsigned char *from, int flen, int num,
     112                 :            :         const unsigned char *param, int plen)
     113                 :            :         {
     114                 :         18 :         return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from , flen, num,
     115                 :            :                                                         param, plen,
     116                 :            :                                                         NULL, NULL);
     117                 :            :         }
     118                 :            : 
     119                 :         20 : int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
     120                 :            :         const unsigned char *from, int flen, int num,
     121                 :            :         const unsigned char *param, int plen,
     122                 :            :         const EVP_MD *md, const EVP_MD *mgf1md)
     123                 :            :         {
     124                 :         20 :         int i, dblen, mlen = -1;
     125                 :            :         const unsigned char *maskeddb;
     126                 :            :         int lzero;
     127                 :         20 :         unsigned char *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
     128                 :            :         unsigned char *padded_from;
     129                 :         20 :         int bad = 0;
     130                 :            :         int mdlen;
     131                 :            : 
     132         [ +  + ]:         20 :         if (md == NULL)
     133                 :         18 :                 md = EVP_sha1();
     134         [ +  + ]:         20 :         if (mgf1md == NULL)
     135                 :         18 :                 mgf1md = md;
     136                 :            : 
     137                 :         20 :         mdlen = EVP_MD_size(md);
     138                 :            : 
     139         [ +  - ]:         20 :         if (--num < 2 * mdlen + 1)
     140                 :            :                 /* 'num' is the length of the modulus, i.e. does not depend on the
     141                 :            :                  * particular ciphertext. */
     142                 :            :                 goto decoding_err;
     143                 :            : 
     144                 :         20 :         lzero = num - flen;
     145         [ +  + ]:         20 :         if (lzero < 0)
     146                 :            :                 {
     147                 :            :                 /* signalling this error immediately after detection might allow
     148                 :            :                  * for side-channel attacks (e.g. timing if 'plen' is huge
     149                 :            :                  * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
     150                 :            :                  * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
     151                 :            :                  * so we use a 'bad' flag */
     152                 :          6 :                 bad = 1;
     153                 :          6 :                 lzero = 0;
     154                 :          6 :                 flen = num; /* don't overflow the memcpy to padded_from */
     155                 :            :                 }
     156                 :            : 
     157                 :         20 :         dblen = num - mdlen;
     158                 :         20 :         db = OPENSSL_malloc(dblen + num);
     159         [ -  + ]:         20 :         if (db == NULL)
     160                 :            :                 {
     161                 :          0 :                 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
     162                 :          0 :                 return -1;
     163                 :            :                 }
     164                 :            : 
     165                 :            :         /* Always do this zero-padding copy (even when lzero == 0)
     166                 :            :          * to avoid leaking timing info about the value of lzero. */
     167                 :         20 :         padded_from = db + dblen;
     168                 :         20 :         memset(padded_from, 0, lzero);
     169                 :         20 :         memcpy(padded_from + lzero, from, flen);
     170                 :            : 
     171                 :         20 :         maskeddb = padded_from + mdlen;
     172                 :            : 
     173         [ +  - ]:         20 :         if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
     174                 :            :                 return -1;
     175         [ +  + ]:        432 :         for (i = 0; i < mdlen; i++)
     176                 :        412 :                 seed[i] ^= padded_from[i];
     177                 :            :   
     178         [ +  - ]:         20 :         if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md))
     179                 :            :                 return -1;
     180         [ +  + ]:       1552 :         for (i = 0; i < dblen; i++)
     181                 :       1532 :                 db[i] ^= maskeddb[i];
     182                 :            : 
     183         [ +  - ]:         20 :         if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
     184                 :            :                 return -1;
     185                 :            : 
     186 [ +  + ][ +  - ]:         20 :         if (CRYPTO_memcmp(db, phash, mdlen) != 0 || bad)
     187                 :            :                 goto decoding_err;
     188                 :            :         else
     189                 :            :                 {
     190         [ +  - ]:        738 :                 for (i = mdlen; i < dblen; i++)
     191         [ +  + ]:        738 :                         if (db[i] != 0x00)
     192                 :            :                                 break;
     193 [ +  - ][ +  - ]:         14 :                 if (i == dblen || db[i] != 0x01)
     194                 :            :                         goto decoding_err;
     195                 :            :                 else
     196                 :            :                         {
     197                 :            :                         /* everything looks OK */
     198                 :            : 
     199                 :         14 :                         mlen = dblen - ++i;
     200         [ -  + ]:         14 :                         if (tlen < mlen)
     201                 :            :                                 {
     202                 :          0 :                                 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE);
     203                 :          0 :                                 mlen = -1;
     204                 :            :                                 }
     205                 :            :                         else
     206                 :         14 :                                 memcpy(to, db + i, mlen);
     207                 :            :                         }
     208                 :            :                 }
     209                 :         14 :         OPENSSL_free(db);
     210                 :         14 :         return mlen;
     211                 :            : 
     212                 :            : decoding_err:
     213                 :            :         /* to avoid chosen ciphertext attacks, the error message should not reveal
     214                 :            :          * which kind of decoding error happened */
     215                 :          6 :         RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_OAEP_DECODING_ERROR);
     216         [ +  - ]:          6 :         if (db != NULL) OPENSSL_free(db);
     217                 :            :         return -1;
     218                 :            :         }
     219                 :            : 
     220                 :         62 : int PKCS1_MGF1(unsigned char *mask, long len,
     221                 :            :         const unsigned char *seed, long seedlen, const EVP_MD *dgst)
     222                 :            :         {
     223                 :         62 :         long i, outlen = 0;
     224                 :            :         unsigned char cnt[4];
     225                 :            :         EVP_MD_CTX c;
     226                 :            :         unsigned char md[EVP_MAX_MD_SIZE];
     227                 :            :         int mdlen;
     228                 :         62 :         int rv = -1;
     229                 :            : 
     230                 :         62 :         EVP_MD_CTX_init(&c);
     231                 :         62 :         mdlen = M_EVP_MD_size(dgst);
     232         [ +  - ]:         62 :         if (mdlen < 0)
     233                 :            :                 goto err;
     234         [ +  + ]:        274 :         for (i = 0; outlen < len; i++)
     235                 :            :                 {
     236                 :        212 :                 cnt[0] = (unsigned char)((i >> 24) & 255);
     237                 :        212 :                 cnt[1] = (unsigned char)((i >> 16) & 255);
     238                 :        212 :                 cnt[2] = (unsigned char)((i >> 8)) & 255;
     239                 :        212 :                 cnt[3] = (unsigned char)(i & 255);
     240         [ +  - ]:        212 :                 if (!EVP_DigestInit_ex(&c,dgst, NULL)
     241         [ +  - ]:        212 :                         || !EVP_DigestUpdate(&c, seed, seedlen)
     242         [ +  - ]:        212 :                         || !EVP_DigestUpdate(&c, cnt, 4))
     243                 :            :                         goto err;
     244         [ +  + ]:        212 :                 if (outlen + mdlen <= len)
     245                 :            :                         {
     246         [ +  - ]:        178 :                         if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
     247                 :            :                                 goto err;
     248                 :            :                         outlen += mdlen;
     249                 :            :                         }
     250                 :            :                 else
     251                 :            :                         {
     252         [ +  - ]:         34 :                         if (!EVP_DigestFinal_ex(&c, md, NULL))
     253                 :            :                                 goto err;
     254                 :         34 :                         memcpy(mask + outlen, md, len - outlen);
     255                 :         34 :                         outlen = len;
     256                 :            :                         }
     257                 :            :                 }
     258                 :            :         rv = 0;
     259                 :            :         err:
     260                 :         62 :         EVP_MD_CTX_cleanup(&c);
     261                 :         62 :         return rv;
     262                 :            :         }
     263                 :            : 
     264                 :            : #endif

Generated by: LCOV version 1.9