4 * This file and its contents are supplied under the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may only use this file in accordance with the terms of version
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.illumos.org/license/CDDL.
17 * Copyright (c) 2017, Datto, Inc. All rights reserved.
22 #include <sys/freebsd_crypto.h>
26 hkdf_sha512_extract(uint8_t *salt
, uint_t salt_len
, uint8_t *key_material
,
27 uint_t km_len
, uint8_t *out_buf
)
31 /* initialize the salt as a crypto key */
32 key
.ck_length
= CRYPTO_BYTES2BITS(salt_len
);
35 crypto_mac(&key
, key_material
, km_len
, out_buf
, SHA512_DIGEST_LENGTH
);
41 hkdf_sha512_expand(uint8_t *extract_key
, uint8_t *info
, uint_t info_len
,
42 uint8_t *out_buf
, uint_t out_len
)
46 uint_t i
, T_len
= 0, pos
= 0;
48 uint_t N
= (out_len
+ SHA512_DIGEST_LENGTH
) / SHA512_DIGEST_LENGTH
;
49 uint8_t T
[SHA512_DIGEST_LENGTH
];
52 return (SET_ERROR(EINVAL
));
54 /* initialize the salt as a crypto key */
55 key
.ck_length
= CRYPTO_BYTES2BITS(SHA512_DIGEST_LENGTH
);
56 key
.ck_data
= extract_key
;
58 for (i
= 1; i
<= N
; i
++) {
61 crypto_mac_init(&ctx
, &key
);
62 crypto_mac_update(&ctx
, T
, T_len
);
63 crypto_mac_update(&ctx
, info
, info_len
);
64 crypto_mac_update(&ctx
, &c
, 1);
65 crypto_mac_final(&ctx
, T
, SHA512_DIGEST_LENGTH
);
66 memcpy(out_buf
+ pos
, T
,
67 (i
!= N
) ? SHA512_DIGEST_LENGTH
: (out_len
- pos
));
68 pos
+= SHA512_DIGEST_LENGTH
;
75 * HKDF is designed to be a relatively fast function for deriving keys from a
76 * master key + a salt. We use this function to generate new encryption keys
77 * so as to avoid hitting the cryptographic limits of the underlying
78 * encryption modes. Note that, for the sake of deriving encryption keys, the
79 * info parameter is called the "salt" everywhere else in the code.
82 hkdf_sha512(uint8_t *key_material
, uint_t km_len
, uint8_t *salt
,
83 uint_t salt_len
, uint8_t *info
, uint_t info_len
, uint8_t *output_key
,
87 uint8_t extract_key
[SHA512_DIGEST_LENGTH
];
89 ret
= hkdf_sha512_extract(salt
, salt_len
, key_material
, km_len
,
94 ret
= hkdf_sha512_expand(extract_key
, info
, info_len
, output_key
,