summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbeck <>2017-05-06 20:42:57 +0000
committerbeck <>2017-05-06 20:42:57 +0000
commit270fd63e5d8c3683472108ff30860e5f0eb33ef1 (patch)
treed7342fea9121d617dc8b0a17a471ebab354fa0ed
parent4b07231945fb22f051b25555dae5b5f56398eee0 (diff)
downloadopenbsd-270fd63e5d8c3683472108ff30860e5f0eb33ef1.tar.gz
openbsd-270fd63e5d8c3683472108ff30860e5f0eb33ef1.tar.bz2
openbsd-270fd63e5d8c3683472108ff30860e5f0eb33ef1.zip
Bring in HKDF, from BoringSSL, with regress tests modified to be
in C. Ride previous minor bump ok tom@ inoguchi@ jsing@
-rw-r--r--src/lib/libcrypto/Makefile7
-rw-r--r--src/lib/libcrypto/hkdf/hkdf.c116
-rw-r--r--src/lib/libcrypto/hkdf/hkdf.h64
-rw-r--r--src/regress/lib/libcrypto/Makefile3
-rw-r--r--src/regress/lib/libcrypto/hkdf/Makefile9
-rw-r--r--src/regress/lib/libcrypto/hkdf/hkdf_test.c299
6 files changed, 496 insertions, 2 deletions
diff --git a/src/lib/libcrypto/Makefile b/src/lib/libcrypto/Makefile
index 13f4ab0de5..6454d6b109 100644
--- a/src/lib/libcrypto/Makefile
+++ b/src/lib/libcrypto/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.16 2017/04/30 04:44:58 jsing Exp $ 1# $OpenBSD: Makefile,v 1.17 2017/05/06 20:42:57 beck Exp $
2 2
3LIB= crypto 3LIB= crypto
4 4
@@ -169,6 +169,9 @@ SRCS+= gost89imit_pmeth.c gost_asn1.c gost_err.c gostr341001.c
169SRCS+= gostr341001_ameth.c gostr341001_key.c gostr341001_params.c 169SRCS+= gostr341001_ameth.c gostr341001_key.c gostr341001_params.c
170SRCS+= gostr341001_pmeth.c gostr341194.c streebog.c 170SRCS+= gostr341001_pmeth.c gostr341194.c streebog.c
171 171
172# hkdf/
173SRCS+= hkdf.c
174
172# hmac/ 175# hmac/
173SRCS+= hmac.c hm_ameth.c hm_pmeth.c 176SRCS+= hmac.c hm_ameth.c hm_pmeth.c
174 177
@@ -287,6 +290,7 @@ SRCS+= pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c
287 ${LCRYPTO_SRC}/err \ 290 ${LCRYPTO_SRC}/err \
288 ${LCRYPTO_SRC}/evp \ 291 ${LCRYPTO_SRC}/evp \
289 ${LCRYPTO_SRC}/gost \ 292 ${LCRYPTO_SRC}/gost \
293 ${LCRYPTO_SRC}/hkdf \
290 ${LCRYPTO_SRC}/hmac \ 294 ${LCRYPTO_SRC}/hmac \
291 ${LCRYPTO_SRC}/idea \ 295 ${LCRYPTO_SRC}/idea \
292 ${LCRYPTO_SRC}/lhash \ 296 ${LCRYPTO_SRC}/lhash \
@@ -344,6 +348,7 @@ HDRS=\
344 ${LCRYPTO_SRC}/err/err.h \ 348 ${LCRYPTO_SRC}/err/err.h \
345 ${LCRYPTO_SRC}/evp/evp.h \ 349 ${LCRYPTO_SRC}/evp/evp.h \
346 ${LCRYPTO_SRC}/gost/gost.h \ 350 ${LCRYPTO_SRC}/gost/gost.h \
351 ${LCRYPTO_SRC}/hkdf/hkdf.h \
347 ${LCRYPTO_SRC}/hmac/hmac.h \ 352 ${LCRYPTO_SRC}/hmac/hmac.h \
348 ${LCRYPTO_SRC}/idea/idea.h \ 353 ${LCRYPTO_SRC}/idea/idea.h \
349 ${LCRYPTO_SRC}/lhash/lhash.h \ 354 ${LCRYPTO_SRC}/lhash/lhash.h \
diff --git a/src/lib/libcrypto/hkdf/hkdf.c b/src/lib/libcrypto/hkdf/hkdf.c
new file mode 100644
index 0000000000..9fe587de13
--- /dev/null
+++ b/src/lib/libcrypto/hkdf/hkdf.c
@@ -0,0 +1,116 @@
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
16#include <openssl/hkdf.h>
17
18#include <assert.h>
19#include <string.h>
20
21#include <openssl/err.h>
22#include <openssl/hmac.h>
23
24/* https://tools.ietf.org/html/rfc5869#section-2 */
25int
26HKDF(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{
30 uint8_t prk[EVP_MAX_MD_SIZE];
31 size_t prk_len;
32
33 if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt,
34 salt_len))
35 return 0;
36 if (!HKDF_expand(out_key, out_len, digest, prk, prk_len, info,
37 info_len))
38 return 0;
39
40 return 1;
41}
42
43/* https://tools.ietf.org/html/rfc5869#section-2.2 */
44int
45HKDF_extract(uint8_t *out_key, size_t *out_len,
46 const EVP_MD *digest, const uint8_t *secret, size_t secret_len,
47 const uint8_t *salt, size_t salt_len)
48{
49 unsigned int len;
50
51 /*
52 * If salt is not given, HashLength zeros are used. However, HMAC does that
53 * internally already so we can ignore it.
54 */
55 if (HMAC(digest, salt, salt_len, secret, secret_len, out_key, &len) ==
56 NULL) {
57 CRYPTOerror(ERR_R_CRYPTO_LIB);
58 return 0;
59 }
60 *out_len = len;
61 return 1;
62}
63
64/* https://tools.ietf.org/html/rfc5869#section-2.3 */
65int
66HKDF_expand(uint8_t *out_key, size_t out_len,
67 const EVP_MD *digest, const uint8_t *prk, size_t prk_len,
68 const uint8_t *info, size_t info_len)
69{
70 const size_t digest_len = EVP_MD_size(digest);
71 uint8_t previous[EVP_MAX_MD_SIZE];
72 size_t n, done = 0;
73 unsigned int i;
74 int ret = 0;
75 HMAC_CTX hmac;
76
77 /* Expand key material to desired length. */
78 n = (out_len + digest_len - 1) / digest_len;
79 if (out_len + digest_len < out_len || n > 255) {
80 CRYPTOerror(EVP_R_TOO_LARGE);
81 return 0;
82 }
83
84 HMAC_CTX_init(&hmac);
85 if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL))
86 goto out;
87
88 for (i = 0; i < n; i++) {
89 uint8_t ctr = i + 1;
90 size_t todo;
91
92 if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) ||
93 !HMAC_Update(&hmac, previous, digest_len)))
94 goto out;
95
96 if (!HMAC_Update(&hmac, info, info_len) ||
97 !HMAC_Update(&hmac, &ctr, 1) ||
98 !HMAC_Final(&hmac, previous, NULL))
99 goto out;
100
101 todo = digest_len;
102 if (done + todo > out_len)
103 todo = out_len - done;
104
105 memcpy(out_key + done, previous, todo);
106 done += todo;
107 }
108
109 ret = 1;
110
111 out:
112 HMAC_CTX_cleanup(&hmac);
113 if (ret != 1)
114 CRYPTOerror(ERR_R_CRYPTO_LIB);
115 return ret;
116}
diff --git a/src/lib/libcrypto/hkdf/hkdf.h b/src/lib/libcrypto/hkdf/hkdf.h
new file mode 100644
index 0000000000..fb0fac37af
--- /dev/null
+++ b/src/lib/libcrypto/hkdf/hkdf.h
@@ -0,0 +1,64 @@
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#ifndef OPENSSL_HEADER_HKDF_H
16#define OPENSSL_HEADER_HKDF_H
17
18#include <openssl/evp.h>
19
20#if defined(__cplusplus)
21extern "C" {
22#endif
23
24/*
25 * HKDF computes HKDF (as specified by RFC 5869) of initial keying
26 * material |secret| with |salt| and |info| using |digest|, and
27 * outputs |out_len| bytes to |out_key|. It returns one on success and
28 * zero on error.
29 *
30 * HKDF is an Extract-and-Expand algorithm. It does not do any key
31 * stretching, and as such, is not suited to be used alone to generate
32 * a key from a password.
33 */
34
35int HKDF(uint8_t *out_key, size_t out_len, const struct env_md_st *digest,
36 const uint8_t *secret, size_t secret_len, const uint8_t *salt,
37 size_t salt_len, const uint8_t *info, size_t info_len);
38
39/*
40 * HKDF_extract computes a HKDF PRK (as specified by RFC 5869) from
41 * initial keying material |secret| and salt |salt| using |digest|,
42 * and outputs |out_len| bytes to |out_key|. The maximum output size
43 * is |EVP_MAX_MD_SIZE|. It returns one on success and zero on error.
44 */
45int HKDF_extract(uint8_t *out_key, size_t *out_len,
46 const struct env_md_st *digest, const uint8_t *secret,
47 size_t secret_len, const uint8_t *salt, size_t salt_len);
48
49/*
50 * HKDF_expand computes a HKDF OKM (as specified by RFC 5869) of
51 * length |out_len| from the PRK |prk| and info |info| using |digest|,
52 * and outputs the result to |out_key|. It returns one on success and
53 * zero on error.
54 */
55int HKDF_expand(uint8_t *out_key, size_t out_len,
56 const EVP_MD *digest, const uint8_t *prk, size_t prk_len,
57 const uint8_t *info, size_t info_len);
58
59
60#if defined(__cplusplus)
61} /* extern C */
62#endif
63
64#endif /* OPENSSL_HEADER_HKDF_H */
diff --git a/src/regress/lib/libcrypto/Makefile b/src/regress/lib/libcrypto/Makefile
index 46f0949035..73059c1c25 100644
--- a/src/regress/lib/libcrypto/Makefile
+++ b/src/regress/lib/libcrypto/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.27 2017/01/25 06:44:22 beck Exp $ 1# $OpenBSD: Makefile,v 1.28 2017/05/06 20:42:57 beck Exp $
2 2
3SUBDIR= \ 3SUBDIR= \
4 aead \ 4 aead \
@@ -23,6 +23,7 @@ SUBDIR= \
23 exp \ 23 exp \
24 gcm128 \ 24 gcm128 \
25 gost \ 25 gost \
26 hkdf \
26 hmac \ 27 hmac \
27 idea \ 28 idea \
28 ige \ 29 ige \
diff --git a/src/regress/lib/libcrypto/hkdf/Makefile b/src/regress/lib/libcrypto/hkdf/Makefile
new file mode 100644
index 0000000000..38d7f5b1f9
--- /dev/null
+++ b/src/regress/lib/libcrypto/hkdf/Makefile
@@ -0,0 +1,9 @@
1# $OpenBSD: Makefile,v 1.1 2017/05/06 20:42:57 beck Exp $
2
3PROG= hkdf_test
4LDADD= -lcrypto
5DPADD= ${LIBCRYPTO}
6WARNINGS= Yes
7CFLAGS+= -DLIBRESSL_INTERNAL
8
9.include <bsd.regress.mk>
diff --git a/src/regress/lib/libcrypto/hkdf/hkdf_test.c b/src/regress/lib/libcrypto/hkdf/hkdf_test.c
new file mode 100644
index 0000000000..3c04262e04
--- /dev/null
+++ b/src/regress/lib/libcrypto/hkdf/hkdf_test.c
@@ -0,0 +1,299 @@
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 <stdio.h>
16#include <string.h>
17
18#include <openssl/crypto.h>
19#include <openssl/evp.h>
20#include <openssl/err.h>
21#include <openssl/hkdf.h>
22
23#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
24
25typedef struct HKDFTestVector_st {
26 const EVP_MD *(*md_func)(void);
27 const uint8_t ikm[80];
28 const size_t ikm_len;
29 const uint8_t salt[80];
30 const size_t salt_len;
31 const uint8_t info[80];
32 const size_t info_len;
33 const uint8_t prk[EVP_MAX_MD_SIZE];
34 const size_t prk_len;
35 const size_t out_len;
36 const uint8_t out[82];
37} HKDFTestVector;
38
39/* These test vectors are from RFC 5869. */
40static const HKDFTestVector kTests[] = {
41 {
42 EVP_sha256,
43 {
44 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
45 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
46 }, 22,
47 {
48 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
49 0x0c,
50 }, 13,
51 {
52 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
53 }, 10,
54 {
55 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f, 0x0d,
56 0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
57 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5,
58 }, 32,
59 42, {
60 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64,
61 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
62 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08,
63 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65
64 }
65 },
66 {
67 EVP_sha256,
68 {
69 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
70 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
71 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
72 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
73 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
74 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
75 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
76 }, 80,
77 {
78 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
79 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
80 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
81 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
82 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
83 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
84 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf
85 }, 80,
86 {
87 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
88 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
89 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
90 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
91 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
92 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
93 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
94 }, 80,
95 {
96 0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a, 0x06, 0x10, 0x4c, 0x9c,
97 0xeb, 0x35, 0xb4, 0x5c, 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01,
98 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44,
99 }, 32,
100 82, {
101 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c,
102 0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
103 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99,
104 0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
105 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9,
106 0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
107 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87
108 }
109 },
110 {
111 EVP_sha256,
112 {
113 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
114 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
115 }, 22,
116 {
117 0,
118 }, 0,
119 {
120 0,
121 }, 0,
122 {
123 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16, 0x7f, 0x33, 0xa9, 0x1d,
124 0x6f, 0x64, 0x8b, 0xdf, 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
125 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04
126 }, 32,
127 42, {
128 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a,
129 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
130 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d, 0x20, 0x13, 0x95,
131 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8
132 }
133 },
134 {
135 EVP_sha1,
136 {
137 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
138 }, 11,
139 {
140 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
141 0x0c,
142 }, 13,
143 {
144 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
145 }, 10,
146 {
147 0x9b, 0x6c, 0x18, 0xc4, 0x32, 0xa7, 0xbf, 0x8f, 0x0e, 0x71, 0xc8, 0xeb,
148 0x88, 0xf4, 0xb3, 0x0b, 0xaa, 0x2b, 0xa2, 0x43
149 }, 20,
150 42, {
151 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, 0x33, 0x06, 0x8b, 0x56,
152 0xef, 0xa5, 0xad, 0x81, 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
153 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2, 0xc2, 0x2e, 0x42, 0x24,
154 0x78, 0xd3, 0x05, 0xf3, 0xf8, 0x96
155 }
156 },
157 {
158 EVP_sha1,
159 {
160 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
161 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
162 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
163 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
164 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
165 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
166 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
167 }, 80,
168 {
169 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
170 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
171 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
172 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
173 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
174 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
175 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf
176 }, 80,
177 {
178 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
179 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
180 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
181 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
182 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
183 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
184 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
185 }, 80,
186 {
187 0x8a, 0xda, 0xe0, 0x9a, 0x2a, 0x30, 0x70, 0x59, 0x47, 0x8d, 0x30, 0x9b,
188 0x26, 0xc4, 0x11, 0x5a, 0x22, 0x4c, 0xfa, 0xf6,
189 }, 20,
190 82, {
191 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, 0xc9, 0xf1, 0x2c, 0xd5,
192 0x91, 0x2a, 0x06, 0xeb, 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
193 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe, 0x8f, 0xa3, 0xf1, 0xa4,
194 0xe5, 0xad, 0x79, 0xf3, 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c,
195 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed, 0x03, 0x4c, 0x7f, 0x9d,
196 0xfe, 0xb1, 0x5c, 0x5e, 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43,
197 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52, 0xd3, 0xb4
198 }
199 },
200 {
201 EVP_sha1,
202 {
203 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
204 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
205 }, 22,
206 {
207 0,
208 }, 0,
209 {
210 0,
211 }, 0,
212 {
213 0xda, 0x8c, 0x8a, 0x73, 0xc7, 0xfa, 0x77, 0x28, 0x8e, 0xc6, 0xf5, 0xe7,
214 0xc2, 0x97, 0x78, 0x6a, 0xa0, 0xd3, 0x2d, 0x01,
215 }, 20,
216 42, {
217 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, 0xd1, 0xe5, 0x52, 0x98,
218 0xda, 0x9d, 0x05, 0x06, 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
219 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0, 0xea, 0x00, 0x03, 0x3d,
220 0xe0, 0x39, 0x84, 0xd3, 0x49, 0x18
221 }
222 },
223 {
224 EVP_sha1,
225 {
226 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
227 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
228 }, 22,
229 {
230 0,
231 }, 0,
232 {
233 0,
234 }, 0,
235 {
236 0x2a, 0xdc, 0xca, 0xda, 0x18, 0x77, 0x9e, 0x7c, 0x20, 0x77, 0xad, 0x2e,
237 0xb1, 0x9d, 0x3f, 0x3e, 0x73, 0x13, 0x85, 0xdd,
238 }, 20,
239 42, {
240 0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3, 0x50, 0x0d, 0x63, 0x6a,
241 0x62, 0xf6, 0x4f, 0x0a, 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
242 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5, 0x67, 0x3a, 0x08, 0x1d,
243 0x70, 0xcc, 0xe7, 0xac, 0xfc, 0x48
244 }
245 },
246};
247
248int main(void) {
249 size_t i;
250 OPENSSL_add_all_algorithms_noconf();
251
252 for (i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
253 const HKDFTestVector *test = &kTests[i];
254 uint8_t prk[EVP_MAX_MD_SIZE];
255 uint8_t buf[82];
256 size_t prk_len;
257 if (!HKDF_extract(prk, &prk_len, test->md_func(), test->ikm,
258 test->ikm_len, test->salt, test->salt_len)) {
259 fprintf(stderr, "Call to HKDF_extract failed\n");
260 ERR_print_errors_fp(stderr);
261 return 1;
262 }
263 if (prk_len != test->prk_len ||
264 memcmp(prk, test->prk, test->prk_len) != 0) {
265 fprintf(stderr, "%zu: Resulting PRK does not match"
266 "test vector\n", i);
267 return 1;
268 }
269 if (!HKDF_expand(buf, test->out_len, test->md_func(), prk, prk_len,
270 test->info, test->info_len)) {
271 fprintf(stderr, "Call to HKDF_expand failed\n");
272 ERR_print_errors_fp(stderr);
273 return 1;
274 }
275 if (memcmp(buf, test->out, test->out_len) != 0) {
276 fprintf(stderr,
277 "%zu: Resulting key material does not match test"
278 "vector\n", i);
279 return 1;
280 }
281
282 if (!HKDF(buf, test->out_len, test->md_func(), test->ikm,
283 test->ikm_len, test->salt, test->salt_len, test->info,
284 test->info_len)) {
285 fprintf(stderr, "Call to HKDF failed\n");
286 ERR_print_errors_fp(stderr);
287 return 1;
288 }
289 if (memcmp(buf, test->out, test->out_len) != 0) {
290 fprintf(stderr,
291 "%zu: Resulting key material does not match test"
292 "vector\n", i);
293 return 1;
294 }
295 }
296
297 printf("PASS\n");
298 return 0;
299}