root/maint/gnulib/lib/gc-pbkdf2.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gc_pbkdf2_prf
  2. gc_pbkdf2_hmac

   1 /* gc-pbkdf2.c --- Password-Based Key Derivation Function a'la PKCS#5
   2    Copyright (C) 2002-2006, 2009-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Simon Josefsson. */
  18 
  19 #include <config.h>
  20 
  21 #include "gc.h"
  22 
  23 #include <stdlib.h>
  24 #include <string.h>
  25 
  26 typedef Gc_rc (*gc_prf_func) (const void *key, size_t keylen,
  27                               const void *in, size_t inlen, char *resbuf);
  28 
  29 static Gc_rc
  30 gc_pbkdf2_prf (gc_prf_func prf, size_t hLen,
     /* [previous][next][first][last][top][bottom][index][help] */
  31                const char *P, size_t Plen,
  32                const char *S, size_t Slen,
  33                unsigned int c,
  34                char *DK, size_t dkLen)
  35 {
  36   char U[GC_MAX_DIGEST_SIZE];
  37   char T[GC_MAX_DIGEST_SIZE];
  38   unsigned int u;
  39   unsigned int l;
  40   unsigned int r;
  41   unsigned int i;
  42   unsigned int k;
  43   int rc;
  44   char *tmp;
  45   size_t tmplen = Slen + 4;
  46 
  47   if (c == 0)
  48     return GC_PKCS5_INVALID_ITERATION_COUNT;
  49 
  50   if (dkLen == 0)
  51     return GC_PKCS5_INVALID_DERIVED_KEY_LENGTH;
  52 
  53   if (dkLen > 4294967295U)
  54     return GC_PKCS5_DERIVED_KEY_TOO_LONG;
  55 
  56   l = ((dkLen - 1) / hLen) + 1;
  57   r = dkLen - (l - 1) * hLen;
  58 
  59   tmp = malloc (tmplen);
  60   if (tmp == NULL)
  61     return GC_MALLOC_ERROR;
  62 
  63   memcpy (tmp, S, Slen);
  64 
  65   for (i = 1; i <= l; i++)
  66     {
  67       memset (T, 0, hLen);
  68 
  69       for (u = 1; u <= c; u++)
  70         {
  71           if (u == 1)
  72             {
  73               tmp[Slen + 0] = (i & 0xff000000) >> 24;
  74               tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
  75               tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
  76               tmp[Slen + 3] = (i & 0x000000ff) >> 0;
  77 
  78               rc = prf (P, Plen, tmp, tmplen, U);
  79             }
  80           else
  81             rc = prf (P, Plen, U, hLen, U);
  82 
  83           if (rc != GC_OK)
  84             {
  85               free (tmp);
  86               return rc;
  87             }
  88 
  89           for (k = 0; k < hLen; k++)
  90             T[k] ^= U[k];
  91         }
  92 
  93       memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
  94     }
  95 
  96   free (tmp);
  97 
  98   return GC_OK;
  99 }
 100 
 101 Gc_rc
 102 gc_pbkdf2_hmac (Gc_hash hash,
     /* [previous][next][first][last][top][bottom][index][help] */
 103                 const char *P, size_t Plen,
 104                 const char *S, size_t Slen,
 105                 unsigned int c, char *DK, size_t dkLen)
 106 {
 107   gc_prf_func prf;
 108   size_t hLen;
 109 
 110   switch (hash)
 111     {
 112 #if GNULIB_GC_HMAC_SHA1
 113     case GC_SHA1:
 114       prf = gc_hmac_sha1;
 115       hLen = GC_SHA1_DIGEST_SIZE;
 116       break;
 117 #endif
 118 
 119 #if GNULIB_GC_HMAC_SHA256
 120     case GC_SHA256:
 121       prf = gc_hmac_sha256;
 122       hLen = GC_SHA256_DIGEST_SIZE;
 123       break;
 124 #endif
 125 
 126 #if GNULIB_GC_HMAC_SHA512
 127     case GC_SHA512:
 128       prf = gc_hmac_sha512;
 129       hLen = GC_SHA512_DIGEST_SIZE;
 130       break;
 131 #endif
 132 
 133     default:
 134       return GC_INVALID_HASH;
 135     }
 136 
 137   return gc_pbkdf2_prf (prf, hLen, P, Plen, S, Slen, c, DK, dkLen);
 138 }

/* [previous][next][first][last][top][bottom][index][help] */