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
uw_crypto_hmac_(const uint8_t * key,size_t key_len,const UwCryptoHmacMsg messages[],size_t num_messages,uint8_t * truncated_digest,size_t truncated_digest_len)14 bool 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