Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
pkcs5.c
00001 /** 00002 * @file pkcs5.c 00003 * @brief PKCS #5 (Password-Based Cryptography Standard) 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include <string.h> 00034 #include "crypto.h" 00035 #include "pkcs5.h" 00036 #include "hmac.h" 00037 00038 //Check crypto library configuration 00039 #if (PKCS5_SUPPORT == ENABLED) 00040 00041 //PKCS #5 OID (1.2.840.113549.1.5) 00042 const uint8_t PKCS5_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05}; 00043 //PBKDF2 OID (1.2.840.113549.1.5.12) 00044 const uint8_t PBKDF2_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C}; 00045 00046 00047 /** 00048 * @brief PBKDF1 key derivation function 00049 * 00050 * PBKDF1 applies a hash function, which shall be MD2, MD5 or SHA-1, to derive 00051 * keys. The length of the derived key is bounded by the length of the hash 00052 * function output, which is 16 octets for MD2 and MD5 and 20 octets for SHA-1 00053 * 00054 * @param[in] hash Underlying hash function (MD2, MD5 or SHA-1) 00055 * @param[in] p Password, an octet string 00056 * @param[in] pLen Length in octets of password 00057 * @param[in] s Salt, an octet string 00058 * @param[in] sLen Length in octets of salt 00059 * @param[in] c Iteration count 00060 * @param[out] dk Derived key 00061 * @param[in] dkLen Intended length in octets of the derived key 00062 * @return Error code 00063 **/ 00064 00065 error_t pbkdf1(const HashAlgo *hash, const uint8_t *p, size_t pLen, 00066 const uint8_t *s, size_t sLen, uint_t c, uint8_t *dk, size_t dkLen) 00067 { 00068 uint_t i; 00069 uint8_t *t; 00070 HashContext *context; 00071 00072 //Check input parameters 00073 if(c < 1 || dkLen > hash->digestSize) 00074 return ERROR_INVALID_PARAMETER; 00075 00076 //Allocate a memory buffer to hold the hash context 00077 context = cryptoAllocMem(hash->contextSize); 00078 //Allocate a temporary buffer 00079 t = cryptoAllocMem(hash->digestSize); 00080 00081 //Failed to allocate memory? 00082 if(!context || !t) 00083 { 00084 //Free previously allocated memory 00085 cryptoFreeMem(context); 00086 cryptoFreeMem(t); 00087 00088 //Report an error 00089 return ERROR_OUT_OF_MEMORY; 00090 } 00091 00092 //Apply the hash function to the concatenation of P and S 00093 hash->init(context); 00094 hash->update(context, p, pLen); 00095 hash->update(context, s, sLen); 00096 hash->final(context, t); 00097 00098 //Iterate as many times as required 00099 for(i = 1; i < c; i++) 00100 { 00101 //Apply the hash function to T(i - 1) 00102 hash->init(context); 00103 hash->update(context, t, hash->digestSize); 00104 hash->final(context, t); 00105 } 00106 00107 //Output the derived key DK 00108 memcpy(dk, t, dkLen); 00109 00110 //Free previously allocated memory 00111 cryptoFreeMem(context); 00112 cryptoFreeMem(t); 00113 00114 //Successful processing 00115 return NO_ERROR; 00116 } 00117 00118 00119 /** 00120 * @brief PBKDF2 key derivation function 00121 * 00122 * PBKDF2 applies a pseudorandom function to derive keys. The 00123 * length of the derived key is essentially unbounded 00124 * 00125 * @param[in] hash Hash algorithm used by the underlying PRF 00126 * @param[in] p Password, an octet string 00127 * @param[in] pLen Length in octets of password 00128 * @param[in] s Salt, an octet string 00129 * @param[in] sLen Length in octets of salt 00130 * @param[in] c Iteration count 00131 * @param[out] dk Derived key 00132 * @param[in] dkLen Intended length in octets of the derived key 00133 * @return Error code 00134 **/ 00135 00136 error_t pbkdf2(const HashAlgo *hash, const uint8_t *p, size_t pLen, 00137 const uint8_t *s, size_t sLen, uint_t c, uint8_t *dk, size_t dkLen) 00138 { 00139 uint_t i; 00140 uint_t j; 00141 uint_t k; 00142 uint8_t *u; 00143 uint8_t *t; 00144 HmacContext *context; 00145 uint8_t a[4]; 00146 00147 //Iteration count must be a positive integer 00148 if(c < 1) 00149 return ERROR_INVALID_PARAMETER; 00150 00151 //Allocate a memory buffer to hold the HMAC context 00152 context = cryptoAllocMem(sizeof(HmacContext)); 00153 //Allocate temporary buffers 00154 u = cryptoAllocMem(hash->digestSize); 00155 t = cryptoAllocMem(hash->digestSize); 00156 00157 //Failed to allocate memory? 00158 if(!context || !u || !t) 00159 { 00160 //Free previously allocated memory 00161 cryptoFreeMem(context); 00162 cryptoFreeMem(u); 00163 cryptoFreeMem(t); 00164 00165 //Report an error 00166 return ERROR_OUT_OF_MEMORY; 00167 } 00168 00169 //For each block of the derived key apply the function F 00170 for(i = 1; dkLen > 0; i++) 00171 { 00172 //Calculate the 4-octet encoding of the integer i (MSB first) 00173 a[0] = (i >> 24) & 0xFF; 00174 a[1] = (i >> 16) & 0xFF; 00175 a[2] = (i >> 8) & 0xFF; 00176 a[3] = i & 0xFF; 00177 00178 //Compute U1 = PRF(P, S || INT(i)) 00179 hmacInit(context, hash, p, pLen); 00180 hmacUpdate(context, s, sLen); 00181 hmacUpdate(context, a, 4); 00182 hmacFinal(context, u); 00183 00184 //Save the resulting HMAC value 00185 memcpy(t, u, hash->digestSize); 00186 00187 //Iterate as many times as required 00188 for(j = 1; j < c; j++) 00189 { 00190 //Compute U(j) = PRF(P, U(j-1)) 00191 hmacInit(context, hash, p, pLen); 00192 hmacUpdate(context, u, hash->digestSize); 00193 hmacFinal(context, u); 00194 00195 //Compute T = U(1) xor U(2) xor ... xor U(c) 00196 for(k = 0; k < hash->digestSize; k++) 00197 t[k] ^= u[k]; 00198 } 00199 00200 //Number of octets in the current block 00201 k = MIN(dkLen, hash->digestSize); 00202 //Save the resulting block 00203 memcpy(dk, t, k); 00204 00205 //Point to the next block 00206 dk += k; 00207 dkLen -= k; 00208 } 00209 00210 //Free previously allocated memory 00211 cryptoFreeMem(context); 00212 cryptoFreeMem(u); 00213 cryptoFreeMem(t); 00214 00215 //Successful processing 00216 return NO_ERROR; 00217 } 00218 00219 #endif 00220
Generated on Tue Jul 12 2022 17:10:15 by
1.7.2