LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/evp - p5_crpt2.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 109 0.0 %
Date: 2015-10-10 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* p5_crpt2.c */
       2             : /*
       3             :  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
       4             :  * 1999.
       5             :  */
       6             : /* ====================================================================
       7             :  * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  *
      13             :  * 1. Redistributions of source code must retain the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer.
      15             :  *
      16             :  * 2. Redistributions in binary form must reproduce the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer in
      18             :  *    the documentation and/or other materials provided with the
      19             :  *    distribution.
      20             :  *
      21             :  * 3. All advertising materials mentioning features or use of this
      22             :  *    software must display the following acknowledgment:
      23             :  *    "This product includes software developed by the OpenSSL Project
      24             :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      25             :  *
      26             :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      27             :  *    endorse or promote products derived from this software without
      28             :  *    prior written permission. For written permission, please contact
      29             :  *    licensing@OpenSSL.org.
      30             :  *
      31             :  * 5. Products derived from this software may not be called "OpenSSL"
      32             :  *    nor may "OpenSSL" appear in their names without prior written
      33             :  *    permission of the OpenSSL Project.
      34             :  *
      35             :  * 6. Redistributions of any form whatsoever must retain the following
      36             :  *    acknowledgment:
      37             :  *    "This product includes software developed by the OpenSSL Project
      38             :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      39             :  *
      40             :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      41             :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      42             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      43             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      44             :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      45             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      46             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      47             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      49             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      50             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      51             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      52             :  * ====================================================================
      53             :  *
      54             :  * This product includes cryptographic software written by Eric Young
      55             :  * (eay@cryptsoft.com).  This product includes software written by Tim
      56             :  * Hudson (tjh@cryptsoft.com).
      57             :  *
      58             :  */
      59             : #include <stdio.h>
      60             : #include <stdlib.h>
      61             : #include "cryptlib.h"
      62             : #if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA)
      63             : # include <openssl/x509.h>
      64             : # include <openssl/evp.h>
      65             : # include <openssl/hmac.h>
      66             : # include "evp_locl.h"
      67             : 
      68             : /* set this to print out info about the keygen algorithm */
      69             : /* #define DEBUG_PKCS5V2 */
      70             : 
      71             : # ifdef DEBUG_PKCS5V2
      72             : static void h__dump(const unsigned char *p, int len);
      73             : # endif
      74             : 
      75             : /*
      76             :  * This is an implementation of PKCS#5 v2.0 password based encryption key
      77             :  * derivation function PBKDF2. SHA1 version verified against test vectors
      78             :  * posted by Peter Gutmann <pgut001@cs.auckland.ac.nz> to the PKCS-TNG
      79             :  * <pkcs-tng@rsa.com> mailing list.
      80             :  */
      81             : 
      82           0 : int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
      83             :                       const unsigned char *salt, int saltlen, int iter,
      84             :                       const EVP_MD *digest, int keylen, unsigned char *out)
      85             : {
      86             :     unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
      87             :     int cplen, j, k, tkeylen, mdlen;
      88             :     unsigned long i = 1;
      89             :     HMAC_CTX hctx_tpl, hctx;
      90             : 
      91           0 :     mdlen = EVP_MD_size(digest);
      92           0 :     if (mdlen < 0)
      93             :         return 0;
      94             : 
      95           0 :     HMAC_CTX_init(&hctx_tpl);
      96             :     p = out;
      97             :     tkeylen = keylen;
      98           0 :     if (!pass)
      99             :         passlen = 0;
     100           0 :     else if (passlen == -1)
     101           0 :         passlen = strlen(pass);
     102           0 :     if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
     103           0 :         HMAC_CTX_cleanup(&hctx_tpl);
     104           0 :         return 0;
     105             :     }
     106           0 :     while (tkeylen) {
     107           0 :         if (tkeylen > mdlen)
     108             :             cplen = mdlen;
     109             :         else
     110             :             cplen = tkeylen;
     111             :         /*
     112             :          * We are unlikely to ever use more than 256 blocks (5120 bits!) but
     113             :          * just in case...
     114             :          */
     115           0 :         itmp[0] = (unsigned char)((i >> 24) & 0xff);
     116           0 :         itmp[1] = (unsigned char)((i >> 16) & 0xff);
     117           0 :         itmp[2] = (unsigned char)((i >> 8) & 0xff);
     118           0 :         itmp[3] = (unsigned char)(i & 0xff);
     119           0 :         if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
     120           0 :             HMAC_CTX_cleanup(&hctx_tpl);
     121           0 :             return 0;
     122             :         }
     123           0 :         if (!HMAC_Update(&hctx, salt, saltlen)
     124           0 :             || !HMAC_Update(&hctx, itmp, 4)
     125           0 :             || !HMAC_Final(&hctx, digtmp, NULL)) {
     126           0 :             HMAC_CTX_cleanup(&hctx_tpl);
     127           0 :             HMAC_CTX_cleanup(&hctx);
     128           0 :             return 0;
     129             :         }
     130           0 :         HMAC_CTX_cleanup(&hctx);
     131           0 :         memcpy(p, digtmp, cplen);
     132           0 :         for (j = 1; j < iter; j++) {
     133           0 :             if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
     134           0 :                 HMAC_CTX_cleanup(&hctx_tpl);
     135           0 :                 return 0;
     136             :             }
     137           0 :             if (!HMAC_Update(&hctx, digtmp, mdlen)
     138           0 :                 || !HMAC_Final(&hctx, digtmp, NULL)) {
     139           0 :                 HMAC_CTX_cleanup(&hctx_tpl);
     140           0 :                 HMAC_CTX_cleanup(&hctx);
     141           0 :                 return 0;
     142             :             }
     143           0 :             HMAC_CTX_cleanup(&hctx);
     144           0 :             for (k = 0; k < cplen; k++)
     145           0 :                 p[k] ^= digtmp[k];
     146             :         }
     147           0 :         tkeylen -= cplen;
     148           0 :         i++;
     149           0 :         p += cplen;
     150             :     }
     151           0 :     HMAC_CTX_cleanup(&hctx_tpl);
     152             : # ifdef DEBUG_PKCS5V2
     153             :     fprintf(stderr, "Password:\n");
     154             :     h__dump(pass, passlen);
     155             :     fprintf(stderr, "Salt:\n");
     156             :     h__dump(salt, saltlen);
     157             :     fprintf(stderr, "Iteration count %d\n", iter);
     158             :     fprintf(stderr, "Key:\n");
     159             :     h__dump(out, keylen);
     160             : # endif
     161           0 :     return 1;
     162             : }
     163             : 
     164           0 : int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
     165             :                            const unsigned char *salt, int saltlen, int iter,
     166             :                            int keylen, unsigned char *out)
     167             : {
     168           0 :     return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
     169             :                              keylen, out);
     170             : }
     171             : 
     172             : # ifdef DO_TEST
     173             : main()
     174             : {
     175             :     unsigned char out[4];
     176             :     unsigned char salt[] = { 0x12, 0x34, 0x56, 0x78 };
     177             :     PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out);
     178             :     fprintf(stderr, "Out %02X %02X %02X %02X\n",
     179             :             out[0], out[1], out[2], out[3]);
     180             : }
     181             : 
     182             : # endif
     183             : 
     184             : /*
     185             :  * Now the key derivation function itself. This is a bit evil because it has
     186             :  * to check the ASN1 parameters are valid: and there are quite a few of
     187             :  * them...
     188             :  */
     189             : 
     190           0 : int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
     191             :                           ASN1_TYPE *param, const EVP_CIPHER *c,
     192             :                           const EVP_MD *md, int en_de)
     193             : {
     194             :     const unsigned char *pbuf;
     195             :     int plen;
     196             :     PBE2PARAM *pbe2 = NULL;
     197             :     const EVP_CIPHER *cipher;
     198             : 
     199             :     int rv = 0;
     200             : 
     201           0 :     if (param == NULL || param->type != V_ASN1_SEQUENCE ||
     202           0 :         param->value.sequence == NULL) {
     203           0 :         EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
     204           0 :         goto err;
     205             :     }
     206             : 
     207           0 :     pbuf = param->value.sequence->data;
     208           0 :     plen = param->value.sequence->length;
     209           0 :     if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
     210           0 :         EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
     211           0 :         goto err;
     212             :     }
     213             : 
     214             :     /* See if we recognise the key derivation function */
     215             : 
     216           0 :     if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
     217           0 :         EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
     218             :                EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
     219           0 :         goto err;
     220             :     }
     221             : 
     222             :     /*
     223             :      * lets see if we recognise the encryption algorithm.
     224             :      */
     225             : 
     226           0 :     cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
     227             : 
     228           0 :     if (!cipher) {
     229           0 :         EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER);
     230           0 :         goto err;
     231             :     }
     232             : 
     233             :     /* Fixup cipher based on AlgorithmIdentifier */
     234           0 :     if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
     235             :         goto err;
     236           0 :     if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
     237           0 :         EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR);
     238           0 :         goto err;
     239             :     }
     240           0 :     rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
     241           0 :                                   pbe2->keyfunc->parameter, c, md, en_de);
     242             :  err:
     243           0 :     PBE2PARAM_free(pbe2);
     244           0 :     return rv;
     245             : }
     246             : 
     247           0 : int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
     248             :                              int passlen, ASN1_TYPE *param,
     249             :                              const EVP_CIPHER *c, const EVP_MD *md, int en_de)
     250             : {
     251             :     unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
     252             :     const unsigned char *pbuf;
     253             :     int saltlen, iter, plen;
     254             :     int rv = 0;
     255             :     unsigned int keylen = 0;
     256             :     int prf_nid, hmac_md_nid;
     257             :     PBKDF2PARAM *kdf = NULL;
     258             :     const EVP_MD *prfmd;
     259             : 
     260           0 :     if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
     261           0 :         EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET);
     262           0 :         goto err;
     263             :     }
     264           0 :     keylen = EVP_CIPHER_CTX_key_length(ctx);
     265           0 :     OPENSSL_assert(keylen <= sizeof key);
     266             : 
     267             :     /* Decode parameter */
     268             : 
     269           0 :     if (!param || (param->type != V_ASN1_SEQUENCE)) {
     270           0 :         EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
     271           0 :         goto err;
     272             :     }
     273             : 
     274           0 :     pbuf = param->value.sequence->data;
     275           0 :     plen = param->value.sequence->length;
     276             : 
     277           0 :     if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen))) {
     278           0 :         EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
     279           0 :         goto err;
     280             :     }
     281             : 
     282           0 :     keylen = EVP_CIPHER_CTX_key_length(ctx);
     283             : 
     284             :     /* Now check the parameters of the kdf */
     285             : 
     286           0 :     if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) {
     287           0 :         EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH);
     288           0 :         goto err;
     289             :     }
     290             : 
     291           0 :     if (kdf->prf)
     292           0 :         prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
     293             :     else
     294             :         prf_nid = NID_hmacWithSHA1;
     295             : 
     296           0 :     if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) {
     297           0 :         EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
     298           0 :         goto err;
     299             :     }
     300             : 
     301           0 :     prfmd = EVP_get_digestbynid(hmac_md_nid);
     302           0 :     if (prfmd == NULL) {
     303           0 :         EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
     304           0 :         goto err;
     305             :     }
     306             : 
     307           0 :     if (kdf->salt->type != V_ASN1_OCTET_STRING) {
     308           0 :         EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE);
     309           0 :         goto err;
     310             :     }
     311             : 
     312             :     /* it seems that its all OK */
     313           0 :     salt = kdf->salt->value.octet_string->data;
     314           0 :     saltlen = kdf->salt->value.octet_string->length;
     315           0 :     iter = ASN1_INTEGER_get(kdf->iter);
     316           0 :     if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
     317             :                            keylen, key))
     318             :         goto err;
     319           0 :     rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
     320             :  err:
     321           0 :     OPENSSL_cleanse(key, keylen);
     322           0 :     PBKDF2PARAM_free(kdf);
     323           0 :     return rv;
     324             : }
     325             : 
     326             : # ifdef DEBUG_PKCS5V2
     327             : static void h__dump(const unsigned char *p, int len)
     328             : {
     329             :     for (; len--; p++)
     330             :         fprintf(stderr, "%02X ", *p);
     331             :     fprintf(stderr, "\n");
     332             : }
     333             : # endif
     334             : #endif

Generated by: LCOV version 1.10