1// Copyright 2015 The Weave Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/crypto_hmac.h" 6 7#include <stddef.h> 8#include <stdint.h> 9#include <string.h> 10 11#include <openssl/evp.h> 12#include <openssl/hmac.h> 13 14bool uw_crypto_hmac_(const uint8_t* key, 15 size_t key_len, 16 const UwCryptoHmacMsg messages[], 17 size_t num_messages, 18 uint8_t* truncated_digest, 19 size_t truncated_digest_len) { 20 HMAC_CTX context = {0}; 21 HMAC_CTX_init(&context); 22 if (!HMAC_Init(&context, key, key_len, EVP_sha256())) 23 return false; 24 25 for (size_t i = 0; i < num_messages; ++i) { 26 if (messages[i].num_bytes && 27 (!messages[i].bytes || 28 !HMAC_Update(&context, messages[i].bytes, messages[i].num_bytes))) { 29 return false; 30 } 31 } 32 33 const size_t kFullDigestLen = (size_t)EVP_MD_size(EVP_sha256()); 34 if (truncated_digest_len > kFullDigestLen) { 35 return false; 36 } 37 38 uint8_t digest[kFullDigestLen]; 39 uint32_t len = kFullDigestLen; 40 41 bool result = HMAC_Final(&context, digest, &len) && kFullDigestLen == len; 42 HMAC_CTX_cleanup(&context); 43 if (result) { 44 memcpy(truncated_digest, digest, truncated_digest_len); 45 } 46 return result; 47} 48