Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
pkcs5.c
Go to the documentation of this file.
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
