hkdf.c
Go to the documentation of this file.
1 /* Copyright (c) 2014, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <openssl/hkdf.h>
16 
17 #include <assert.h>
18 #include <string.h>
19 
20 #include <openssl/err.h>
21 #include <openssl/hmac.h>
22 
23 #include "../internal.h"
24 
25 
26 int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest,
27  const uint8_t *secret, size_t secret_len, const uint8_t *salt,
28  size_t salt_len, const uint8_t *info, size_t info_len) {
29  // https://tools.ietf.org/html/rfc5869#section-2
31  size_t prk_len;
32 
33  if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt,
34  salt_len) ||
35  !HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)) {
36  return 0;
37  }
38 
39  return 1;
40 }
41 
42 int HKDF_extract(uint8_t *out_key, size_t *out_len, const EVP_MD *digest,
43  const uint8_t *secret, size_t secret_len, const uint8_t *salt,
44  size_t salt_len) {
45  // https://tools.ietf.org/html/rfc5869#section-2.2
46 
47  // If salt is not given, HashLength zeros are used. However, HMAC does that
48  // internally already so we can ignore it.
49  unsigned len;
50  if (HMAC(digest, salt, salt_len, secret, secret_len, out_key, &len) == NULL) {
52  return 0;
53  }
54  *out_len = len;
55  assert(*out_len == EVP_MD_size(digest));
56  return 1;
57 }
58 
59 int HKDF_expand(uint8_t *out_key, size_t out_len, const EVP_MD *digest,
60  const uint8_t *prk, size_t prk_len, const uint8_t *info,
61  size_t info_len) {
62  // https://tools.ietf.org/html/rfc5869#section-2.3
63  const size_t digest_len = EVP_MD_size(digest);
65  size_t n, done = 0;
66  unsigned i;
67  int ret = 0;
68  HMAC_CTX hmac;
69 
70  // Expand key material to desired length.
71  n = (out_len + digest_len - 1) / digest_len;
72  if (out_len + digest_len < out_len || n > 255) {
74  return 0;
75  }
76 
77  HMAC_CTX_init(&hmac);
78  if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL)) {
79  goto out;
80  }
81 
82  for (i = 0; i < n; i++) {
83  uint8_t ctr = i + 1;
84  size_t todo;
85 
86  if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) ||
87  !HMAC_Update(&hmac, previous, digest_len))) {
88  goto out;
89  }
90  if (!HMAC_Update(&hmac, info, info_len) ||
91  !HMAC_Update(&hmac, &ctr, 1) ||
92  !HMAC_Final(&hmac, previous, NULL)) {
93  goto out;
94  }
95 
96  todo = digest_len;
97  if (done + todo > out_len) {
98  todo = out_len - done;
99  }
100  OPENSSL_memcpy(out_key + done, previous, todo);
101  done += todo;
102  }
103 
104  ret = 1;
105 
106 out:
107  HMAC_CTX_cleanup(&hmac);
108  if (ret != 1) {
110  }
111  return ret;
112 }
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
HKDF_expand
int HKDF_expand(uint8_t *out_key, size_t out_len, const EVP_MD *digest, const uint8_t *prk, size_t prk_len, const uint8_t *info, size_t info_len)
Definition: hkdf.c:59
env_md_st
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/internal.h:67
generate_changelog.previous
previous
Definition: bloaty/third_party/protobuf/generate_changelog.py:55
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
string.h
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
HKDF
int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, const uint8_t *secret, size_t secret_len, const uint8_t *salt, size_t salt_len, const uint8_t *info, size_t info_len)
Definition: hkdf.c:26
HMAC_CTX_init
#define HMAC_CTX_init
Definition: boringssl_prefix_symbols.h:1788
ERR_R_HMAC_LIB
#define ERR_R_HMAC_LIB
Definition: err.h:361
EVP_MD_size
#define EVP_MD_size
Definition: boringssl_prefix_symbols.h:1579
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
err.h
HMAC_Init_ex
#define HMAC_Init_ex
Definition: boringssl_prefix_symbols.h:1793
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
HMAC_Final
#define HMAC_Final
Definition: boringssl_prefix_symbols.h:1791
hkdf.h
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
hmac_ctx_st
Definition: hmac.h:158
EVP_MAX_MD_SIZE
#define EVP_MAX_MD_SIZE
Definition: digest.h:156
HMAC
#define HMAC
Definition: boringssl_prefix_symbols.h:1783
HMAC_CTX_cleanup
#define HMAC_CTX_cleanup
Definition: boringssl_prefix_symbols.h:1784
HKDF_extract
int HKDF_extract(uint8_t *out_key, size_t *out_len, const EVP_MD *digest, const uint8_t *secret, size_t secret_len, const uint8_t *salt, size_t salt_len)
Definition: hkdf.c:42
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
HKDF_R_OUTPUT_TOO_LARGE
#define HKDF_R_OUTPUT_TOO_LARGE
Definition: hkdf.h:66
mkowners.todo
todo
Definition: mkowners.py:209
HMAC_Update
#define HMAC_Update
Definition: boringssl_prefix_symbols.h:1794
hmac.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:01