Hkdf.c Source Code - HKDF (HMAC-based Key Derivation Function)

Toggle navigation
  • Home
  • CycloneTCP
  • CycloneSSL
  • CycloneSSH
  • CycloneIPSEC
  • CycloneSTP
  • CycloneACME
  • CycloneCRYPTO
  • Download
  • Main Page
  • Data Structures
  • Files
  • File List
  • Globals
  • cyclone_crypto
  • kdf
hkdf.c Go to the documentation of this file. 1 /** 2  * @file hkdf.c 3  * @brief HKDF (HMAC-based Key Derivation Function) 4  * 5  * @section License 6  * 7  * SPDX-License-Identifier: GPL-2.0-or-later 8  * 9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved. 10  * 11  * This file is part of CycloneCRYPTO Open. 12  * 13  * This program is free software; you can redistribute it and/or 14  * modify it under the terms of the GNU General Public License 15  * as published by the Free Software Foundation; either version 2 16  * of the License, or (at your option) any later version. 17  * 18  * This program is distributed in the hope that it will be useful, 19  * but WITHOUT ANY WARRANTY; without even the implied warranty of 20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21  * GNU General Public License for more details. 22  * 23  * You should have received a copy of the GNU General Public License 24  * along with this program; if not, write to the Free Software Foundation, 25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26  * 27  * @section Description 28  * 29  * HKDF is a simple HMAC-based key derivation function which can be used as a 30  * building block in various protocols and applications. Refer to RFC 5869 for 31  * more details 32  * 33  * @author Oryx Embedded SARL (www.oryx-embedded.com) 34  * @version 2.6.0 35  **/ 36  37 //Switch to the appropriate trace level 38 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 39  40 //Dependencies 41 #include "core/crypto.h" 42 #include "kdf/hkdf.h" 43 #include "mac/hmac.h" 44  45 //Check crypto library configuration 46 #if (HKDF_SUPPORT == ENABLED) 47  48  49 /** 50  * @brief HKDF key derivation function 51  * @param[in] hash Underlying hash function 52  * @param[in] ikm input keying material 53  * @param[in] ikmLen Length in the input keying material 54  * @param[in] salt Optional salt value (a non-secret random value) 55  * @param[in] saltLen Length of the salt 56  * @param[in] info Optional application specific information 57  * @param[in] infoLen Length of the application specific information 58  * @param[out] okm output keying material 59  * @param[in] okmLen Length of the output keying material 60  * @return Error code 61  **/ 62  63 error_t hkdf(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen, 64  const uint8_t *salt, size_t saltLen, const uint8_t *info, size_t infoLen, 65  uint8_t *okm, size_t okmLen) 66 { 67  error_t error; 68  uint8_t prk[MAX_HASH_DIGEST_SIZE]; 69  70  //Perform HKDF extract step 71  error = hkdfExtract(hash, ikm, ikmLen, salt, saltLen, prk); 72  73  //Check status code 74  if(!error) 75  { 76  //Perform HKDF expand step 77  error = hkdfExpand(hash, prk, hash->digestSize, info, infoLen, 78  okm, okmLen); 79  } 80  81  //Return status code 82  return error; 83 } 84  85  86 /** 87  * @brief HKDF extract step 88  * @param[in] hash Underlying hash function 89  * @param[in] ikm input keying material 90  * @param[in] ikmLen Length in the input keying material 91  * @param[in] salt Optional salt value (a non-secret random value) 92  * @param[in] saltLen Length of the salt 93  * @param[out] prk Pseudorandom key 94  * @return Error code 95  **/ 96  97 error_t hkdfExtract(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen, 98  const uint8_t *salt, size_t saltLen, uint8_t *prk) 99 { 100 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED) 101  HmacContext *hmacContext; 102 #else 103  HmacContext hmacContext[1]; 104 #endif 105  106  //Check parameters 107  if(hash == NULL || ikm == NULL || prk == NULL) 108  return ERROR_INVALID_PARAMETER; 109  110  //The salt parameter is optional 111  if(salt == NULL && saltLen != 0) 112  return ERROR_INVALID_PARAMETER; 113  114 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED) 115  //Allocate a memory buffer to hold the HMAC context 116  hmacContext = cryptoAllocMem(sizeof(HmacContext)); 117  //Failed to allocate memory? 118  if(hmacContext == NULL) 119  return ERROR_OUT_OF_MEMORY; 120 #endif 121  122  //The salt parameter is optional 123  if(salt == NULL) 124  { 125  //If the salt is not provided, it is set to a string of HashLen zeros 126  osMemset(hmacContext->digest, 0, hash->digestSize); 127  salt = hmacContext->digest; 128  saltLen = hash->digestSize; 129  } 130  131  //Compute PRK = HMAC-Hash(salt, IKM) 132  hmacInit(hmacContext, hash, salt, saltLen); 133  hmacUpdate(hmacContext, ikm, ikmLen); 134  hmacFinal(hmacContext, prk); 135  136 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED) 137  //Free previously allocated memory 138  cryptoFreeMem(hmacContext); 139 #endif 140  141  //Successful processing 142  return NO_ERROR; 143 } 144  145  146 /** 147  * @brief HKDF expand step 148  * @param[in] hash Underlying hash function 149  * @param[in] prk Pseudorandom key 150  * @param[in] prkLen Length of the pseudorandom key 151  * @param[in] info Optional application specific information 152  * @param[in] infoLen Length of the application specific information 153  * @param[out] okm output keying material 154  * @param[in] okmLen Length of the output keying material 155  * @return Error code 156  **/ 157  158 error_t hkdfExpand(const HashAlgo *hash, const uint8_t *prk, size_t prkLen, 159  const uint8_t *info, size_t infoLen, uint8_t *okm, size_t okmLen) 160 { 161  uint8_t i; 162  size_t tLen; 163  uint8_t t[MAX_HASH_DIGEST_SIZE]; 164 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED) 165  HmacContext *hmacContext; 166 #else 167  HmacContext hmacContext[1]; 168 #endif 169  170  //Check parameters 171  if(hash == NULL || prk == NULL || okm == NULL) 172  return ERROR_INVALID_PARAMETER; 173  174  //The application specific information parameter is optional 175  if(info == NULL && infoLen != 0) 176  return ERROR_INVALID_PARAMETER; 177  178  //PRK must be at least HashLen octets 179  if(prkLen < hash->digestSize) 180  return ERROR_INVALID_LENGTH; 181  182  //Check the length of the output keying material 183  if(okmLen > (255 * hash->digestSize)) 184  return ERROR_INVALID_LENGTH; 185  186 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED) 187  //Allocate a memory buffer to hold the HMAC context 188  hmacContext = cryptoAllocMem(sizeof(HmacContext)); 189  //Failed to allocate memory? 190  if(hmacContext == NULL) 191  return ERROR_OUT_OF_MEMORY; 192 #endif 193  194  //T(0) is an empty string (zero length) 195  tLen = 0; 196  197  //Iterate as many times as required 198  for(i = 1; okmLen > 0; i++) 199  { 200  //Compute T(i) = HMAC-Hash(PRK, T(i-1) | info | i) 201  hmacInit(hmacContext, hash, prk, prkLen); 202  hmacUpdate(hmacContext, t, tLen); 203  hmacUpdate(hmacContext, info, infoLen); 204  hmacUpdate(hmacContext, &i, sizeof(i)); 205  hmacFinal(hmacContext, t); 206  207  //Number of octets in the current block 208  tLen = MIN(okmLen, hash->digestSize); 209  //Save the resulting block 210  osMemcpy(okm, t, tLen); 211  212  //Point to the next block 213  okm += tLen; 214  okmLen -= tLen; 215  } 216  217 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED) 218  //Free previously allocated memory 219  cryptoFreeMem(hmacContext); 220 #endif 221  222  //Successful processing 223  return NO_ERROR; 224 } 225  226 #endif HmacContextHMAC algorithm context.Definition: hmac.h:59 tuint8_t tDefinition: lldp_ext_med.h:212 HashAlgo::digestSizesize_t digestSizeDefinition: crypto.h:1157 ERROR_OUT_OF_MEMORY@ ERROR_OUT_OF_MEMORYDefinition: error.h:63 MAX_HASH_DIGEST_SIZE#define MAX_HASH_DIGEST_SIZEDefinition: hash_algorithms.h:238 ERROR_INVALID_PARAMETER@ ERROR_INVALID_PARAMETERInvalid parameter.Definition: error.h:47 osMemcpy#define osMemcpy(dest, src, length)Definition: os_port.h:144 error_terror_tError codes.Definition: error.h:43 ERROR_INVALID_LENGTH@ ERROR_INVALID_LENGTHDefinition: error.h:111 crypto.hGeneral definitions for cryptographic algorithms. hkdfExpanderror_t hkdfExpand(const HashAlgo *hash, const uint8_t *prk, size_t prkLen, const uint8_t *info, size_t infoLen, uint8_t *okm, size_t okmLen)HKDF expand step.Definition: hkdf.c:158 MIN#define MIN(a, b)Definition: os_port.h:63 hmacUpdate__weak_func void hmacUpdate(HmacContext *context, const void *data, size_t length)Update the HMAC context with a portion of the message being hashed.Definition: hmac.c:201 HmacContext::digestuint8_t digest[MAX_HASH_DIGEST_SIZE]Definition: hmac.h:63 hkdf.hHKDF (HMAC-based Key Derivation Function) hmacFinal__weak_func void hmacFinal(HmacContext *context, uint8_t *digest)Finish the HMAC calculation.Definition: hmac.c:218 hkdferror_t hkdf(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen, const uint8_t *salt, size_t saltLen, const uint8_t *info, size_t infoLen, uint8_t *okm, size_t okmLen)HKDF key derivation function.Definition: hkdf.c:63 cryptoFreeMem#define cryptoFreeMem(p)Definition: crypto.h:861 cryptoAllocMem#define cryptoAllocMem(size)Definition: crypto.h:856 HashAlgoCommon interface for hash algorithms.Definition: crypto.h:1151 hkdfExtracterror_t hkdfExtract(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen, const uint8_t *salt, size_t saltLen, uint8_t *prk)HKDF extract step.Definition: hkdf.c:97 osMemset#define osMemset(p, value, length)Definition: os_port.h:138 hmacInit__weak_func error_t hmacInit(HmacContext *context, const HashAlgo *hash, const void *key, size_t keyLen)Initialize HMAC calculation.Definition: hmac.c:140 NO_ERROR@ NO_ERRORSuccess.Definition: error.h:44 hmac.hHMAC (Keyed-Hashing for Message Authentication) Copyright © 2023 Oryx Embedded SARL. All Rights Reserved. Contact Terms Privacy

Từ khóa » C Hkdf