1 #define _POSIX_C_SOURCE 200809L
13 #include <sys/socket.h>
14 #include <arpa/inet.h>
22 int tls_hkdf_extract(unsigned int mac_length,
23 unsigned char *output, unsigned int outlen,
24 const unsigned char *salt,
25 unsigned int salt_len,
26 const unsigned char *ikm,
27 unsigned char ikm_len) {
29 unsigned long dlen = outlen;
30 unsigned char dummy_label[1] = { 0 };
32 if (!salt || salt_len == 0) {
37 if (mac_length == TLS_SHA384_MAC_SIZE) {
38 hash_idx = find_hash("sha384");
41 hash_idx = find_hash("sha256");
44 hmac_memory(hash_idx, salt, salt_len, ikm, ikm_len, output, &dlen);
48 static int make_hkdf_label(const char *label, unsigned char label_len,
49 const unsigned char *data,
50 unsigned char data_len,
51 unsigned char *hkdflabel,
52 unsigned short length, const char *prefix) {
54 *(unsigned short *) &hkdflabel[0] = htons(length);
57 prefix_len = strlen(prefix);
58 memcpy(&hkdflabel[3], prefix, prefix_len);
60 memcpy(&hkdflabel[3], "tls13 ", 6);
64 hkdflabel[2] = (unsigned char) prefix_len + label_len;
66 memcpy(&hkdflabel[3 + prefix_len], label, label_len);
68 hkdflabel[3 + prefix_len + label_len] = data_len;
71 memcpy(&hkdflabel[4 + prefix_len + label_len], data,
75 return 4 + prefix_len + label_len + data_len;
78 void tls_hkdf_expand(unsigned int mac_length,
79 unsigned char *output, unsigned int outlen,
80 const unsigned char *secret,
81 unsigned int secret_len,
82 const unsigned char *info,
83 unsigned char info_len) {
84 unsigned char digest_out[TLS_MAX_HASH_LEN];
85 unsigned long dlen = 32;
93 if (mac_length == TLS_SHA384_MAC_SIZE) {
94 hash_idx = find_hash("sha384");
97 hash_idx = find_hash("sha256");
101 hmac_init(&hmac, hash_idx, secret, secret_len);
103 hmac_process(&hmac, digest_out, dlen);
105 if (info && info_len) {
106 hmac_process(&hmac, info, info_len);
109 hmac_process(&hmac, &i2, 1);
110 hmac_done(&hmac, digest_out, &dlen);
113 if (copylen > dlen) {
114 copylen = (unsigned int) dlen;
117 for (i = 0; i < copylen; i++) {
118 output[idx++] = digest_out[i];
124 void tls_hkdf_expand_label(unsigned int mac_length, unsigned char *output,
125 unsigned int outlen, const unsigned char *secret, unsigned int
126 secret_len, const char *label, unsigned char label_len, const
127 unsigned char *data, unsigned char data_len) {
128 unsigned char hkdf_label[512];
129 int len = make_hkdf_label(label, label_len, data, data_len, hkdf_label,
131 tls_hkdf_expand(mac_length, output, outlen, secret, secret_len,