mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2025-01-15 11:05:18 +00:00
304 lines
9.4 KiB
C
304 lines
9.4 KiB
C
|
/**
|
||
|
* @file hmac.c
|
||
|
* @brief HMAC (Keyed-Hashing for Message Authentication)
|
||
|
*
|
||
|
* @section License
|
||
|
*
|
||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||
|
*
|
||
|
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
|
||
|
*
|
||
|
* This file is part of CycloneCRYPTO Open.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software Foundation,
|
||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
* @section Description
|
||
|
*
|
||
|
* HMAC is a mechanism for message authentication using cryptographic hash
|
||
|
* functions. HMAC can be used with any iterative cryptographic hash
|
||
|
* function (MD5, SHA-1 or SHA-256) in combination with a secret shared
|
||
|
* key. Refer to RFC 2104 for more details
|
||
|
*
|
||
|
* @author Oryx Embedded SARL (www.oryx-embedded.com)
|
||
|
* @version 2.4.4
|
||
|
**/
|
||
|
|
||
|
//Switch to the appropriate trace level
|
||
|
#define TRACE_LEVEL CRYPTO_TRACE_LEVEL
|
||
|
|
||
|
//Dependencies
|
||
|
#include "core/crypto.h"
|
||
|
#include "mac/hmac.h"
|
||
|
|
||
|
//Check crypto library configuration
|
||
|
#if (HMAC_SUPPORT == ENABLED)
|
||
|
|
||
|
//HMAC with MD5 OID (1.3.6.1.5.5.8.1.1)
|
||
|
const uint8_t HMAC_WITH_MD5_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x01};
|
||
|
//HMAC with Tiger OID (1.3.6.1.5.5.8.1.3)
|
||
|
const uint8_t HMAC_WITH_TIGER_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x03};
|
||
|
//HMAC with RIPEMD-160 OID (1.3.6.1.5.5.8.1.4)
|
||
|
const uint8_t HMAC_WITH_RIPEMD160_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x04};
|
||
|
//HMAC with SHA-1 OID (1.2.840.113549.2.7)
|
||
|
const uint8_t HMAC_WITH_SHA1_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x07};
|
||
|
//HMAC with SHA-224 OID (1.2.840.113549.2.8)
|
||
|
const uint8_t HMAC_WITH_SHA224_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x08};
|
||
|
//HMAC with SHA-256 OID (1.2.840.113549.2.9)
|
||
|
const uint8_t HMAC_WITH_SHA256_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x09};
|
||
|
//HMAC with SHA-384 OID (1.2.840.113549.2.10)
|
||
|
const uint8_t HMAC_WITH_SHA384_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0A};
|
||
|
//HMAC with SHA-512 OID (1.2.840.113549.2.11)
|
||
|
const uint8_t HMAC_WITH_SHA512_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0B};
|
||
|
//HMAC with SHA-512/224 OID (1.2.840.113549.2.12)
|
||
|
const uint8_t HMAC_WITH_SHA512_224_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0C};
|
||
|
//HMAC with SHA-512/256 OID (1.2.840.113549.2.13)
|
||
|
const uint8_t HMAC_WITH_SHA512_256_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0D};
|
||
|
//HMAC with SHA-3-224 OID (2.16.840.1.101.3.4.2.13)
|
||
|
const uint8_t HMAC_WITH_SHA3_224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0D};
|
||
|
//HMAC with SHA-3-256 OID (2.16.840.1.101.3.4.2.14)
|
||
|
const uint8_t HMAC_WITH_SHA3_256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0E};
|
||
|
//HMAC with SHA-3-384 OID (2.16.840.1.101.3.4.2.15)
|
||
|
const uint8_t HMAC_WITH_SHA3_384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0F};
|
||
|
//HMAC with SHA-3-512 OID (2.16.840.1.101.3.4.2.16)
|
||
|
const uint8_t HMAC_WITH_SHA3_512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x10};
|
||
|
//HMAC with SM3 OID (1.2.156.10197.1.401.3.1)
|
||
|
const uint8_t HMAC_WITH_SM3_OID[10] = {0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x91, 0x03, 0x01};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Compute HMAC using the specified hash function
|
||
|
* @param[in] hash Hash algorithm used to compute HMAC
|
||
|
* @param[in] key Key to use in the hash algorithm
|
||
|
* @param[in] keyLen Length of the key
|
||
|
* @param[in] data The input data for which to compute the hash code
|
||
|
* @param[in] dataLen Length of the input data
|
||
|
* @param[out] digest The computed HMAC value
|
||
|
* @return Error code
|
||
|
**/
|
||
|
|
||
|
__weak_func error_t hmacCompute(const HashAlgo *hash, const void *key, size_t keyLen,
|
||
|
const void *data, size_t dataLen, uint8_t *digest)
|
||
|
{
|
||
|
error_t error;
|
||
|
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
|
||
|
HmacContext *context;
|
||
|
#else
|
||
|
HmacContext context[1];
|
||
|
#endif
|
||
|
|
||
|
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
|
||
|
//Allocate a memory buffer to hold the HMAC context
|
||
|
context = cryptoAllocMem(sizeof(HmacContext));
|
||
|
//Failed to allocate memory?
|
||
|
if(context == NULL)
|
||
|
return ERROR_OUT_OF_MEMORY;
|
||
|
#endif
|
||
|
|
||
|
//Initialize the HMAC context
|
||
|
error = hmacInit(context, hash, key, keyLen);
|
||
|
|
||
|
//Check status code
|
||
|
if(!error)
|
||
|
{
|
||
|
//Digest the message
|
||
|
hmacUpdate(context, data, dataLen);
|
||
|
//Finalize the HMAC computation
|
||
|
hmacFinal(context, digest);
|
||
|
}
|
||
|
|
||
|
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
|
||
|
//Free previously allocated memory
|
||
|
cryptoFreeMem(context);
|
||
|
#endif
|
||
|
|
||
|
//Return status code
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Initialize HMAC calculation
|
||
|
* @param[in] context Pointer to the HMAC context to initialize
|
||
|
* @param[in] hash Hash algorithm used to compute HMAC
|
||
|
* @param[in] key Key to use in the hash algorithm
|
||
|
* @param[in] keyLen Length of the key
|
||
|
* @return Error code
|
||
|
**/
|
||
|
|
||
|
__weak_func error_t hmacInit(HmacContext *context, const HashAlgo *hash,
|
||
|
const void *key, size_t keyLen)
|
||
|
{
|
||
|
uint_t i;
|
||
|
|
||
|
//Check parameters
|
||
|
if(context == NULL || hash == NULL)
|
||
|
return ERROR_INVALID_PARAMETER;
|
||
|
|
||
|
//Make sure the supplied key is valid
|
||
|
if(key == NULL && keyLen != 0)
|
||
|
return ERROR_INVALID_PARAMETER;
|
||
|
|
||
|
//Hash algorithm used to compute HMAC
|
||
|
context->hash = hash;
|
||
|
|
||
|
//The key is longer than the block size?
|
||
|
if(keyLen > hash->blockSize)
|
||
|
{
|
||
|
//Initialize the hash function context
|
||
|
hash->init(&context->hashContext);
|
||
|
//Digest the original key
|
||
|
hash->update(&context->hashContext, key, keyLen);
|
||
|
//Finalize the message digest computation
|
||
|
hash->final(&context->hashContext, context->key);
|
||
|
|
||
|
//Key is padded to the right with extra zeros
|
||
|
osMemset(context->key + hash->digestSize, 0,
|
||
|
hash->blockSize - hash->digestSize);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//Copy the key
|
||
|
osMemcpy(context->key, key, keyLen);
|
||
|
//Key is padded to the right with extra zeros
|
||
|
osMemset(context->key + keyLen, 0, hash->blockSize - keyLen);
|
||
|
}
|
||
|
|
||
|
//XOR the resulting key with ipad
|
||
|
for(i = 0; i < hash->blockSize; i++)
|
||
|
{
|
||
|
context->key[i] ^= HMAC_IPAD;
|
||
|
}
|
||
|
|
||
|
//Initialize context for the first pass
|
||
|
hash->init(&context->hashContext);
|
||
|
//Start with the inner pad
|
||
|
hash->update(&context->hashContext, context->key, hash->blockSize);
|
||
|
|
||
|
//Successful initialization
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Update the HMAC context with a portion of the message being hashed
|
||
|
* @param[in] context Pointer to the HMAC context
|
||
|
* @param[in] data Pointer to the buffer being hashed
|
||
|
* @param[in] length Length of the buffer
|
||
|
**/
|
||
|
|
||
|
__weak_func void hmacUpdate(HmacContext *context, const void *data, size_t length)
|
||
|
{
|
||
|
const HashAlgo *hash;
|
||
|
|
||
|
//Hash algorithm used to compute HMAC
|
||
|
hash = context->hash;
|
||
|
//Digest the message (first pass)
|
||
|
hash->update(&context->hashContext, data, length);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Finish the HMAC calculation
|
||
|
* @param[in] context Pointer to the HMAC context
|
||
|
* @param[out] digest Calculated HMAC value (optional parameter)
|
||
|
**/
|
||
|
|
||
|
__weak_func void hmacFinal(HmacContext *context, uint8_t *digest)
|
||
|
{
|
||
|
uint_t i;
|
||
|
const HashAlgo *hash;
|
||
|
|
||
|
//Hash algorithm used to compute HMAC
|
||
|
hash = context->hash;
|
||
|
//Finish the first pass
|
||
|
hash->final(&context->hashContext, context->digest);
|
||
|
|
||
|
//XOR the original key with opad
|
||
|
for(i = 0; i < hash->blockSize; i++)
|
||
|
{
|
||
|
context->key[i] ^= HMAC_IPAD ^ HMAC_OPAD;
|
||
|
}
|
||
|
|
||
|
//Initialize context for the second pass
|
||
|
hash->init(&context->hashContext);
|
||
|
//Start with outer pad
|
||
|
hash->update(&context->hashContext, context->key, hash->blockSize);
|
||
|
//Then digest the result of the first hash
|
||
|
hash->update(&context->hashContext, context->digest, hash->digestSize);
|
||
|
//Finish the second pass
|
||
|
hash->final(&context->hashContext, context->digest);
|
||
|
|
||
|
//Copy the resulting HMAC value
|
||
|
if(digest != NULL)
|
||
|
{
|
||
|
osMemcpy(digest, context->digest, hash->digestSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Release HMAC context
|
||
|
* @param[in] context Pointer to the HMAC context
|
||
|
**/
|
||
|
|
||
|
void hmacDeinit(HmacContext *context)
|
||
|
{
|
||
|
//Make sure the HMAC context is valid
|
||
|
if(context != NULL)
|
||
|
{
|
||
|
//Clear HMAC context
|
||
|
osMemset(context, 0, sizeof(HmacContext));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Finish the HMAC calculation (no padding added)
|
||
|
* @param[in] context Pointer to the HMAC context
|
||
|
* @param[out] digest Calculated HMAC value (optional parameter)
|
||
|
**/
|
||
|
|
||
|
void hmacFinalRaw(HmacContext *context, uint8_t *digest)
|
||
|
{
|
||
|
uint_t i;
|
||
|
const HashAlgo *hash;
|
||
|
|
||
|
//Hash algorithm used to compute HMAC
|
||
|
hash = context->hash;
|
||
|
|
||
|
//XOR the original key with opad
|
||
|
for(i = 0; i < hash->blockSize; i++)
|
||
|
{
|
||
|
context->key[i] ^= HMAC_IPAD ^ HMAC_OPAD;
|
||
|
}
|
||
|
|
||
|
//Initialize context for the second pass
|
||
|
hash->init(&context->hashContext);
|
||
|
//Start with outer pad
|
||
|
hash->update(&context->hashContext, context->key, hash->blockSize);
|
||
|
//Then digest the result of the first hash
|
||
|
hash->update(&context->hashContext, context->digest, hash->digestSize);
|
||
|
//Finish the second pass
|
||
|
hash->final(&context->hashContext, context->digest);
|
||
|
|
||
|
//Copy the resulting HMAC value
|
||
|
if(digest != NULL)
|
||
|
{
|
||
|
osMemcpy(digest, context->digest, hash->digestSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|