Home | History | Annotate | Download | only in src
      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 
     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