]> pd.if.org Git - zpackage/blob - crypto/hkdf.c
fix some todo items
[zpackage] / crypto / hkdf.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <fcntl.h>
4 #include <stdint.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <strings.h>
9 #include <sys/mman.h>
10 #include <sys/stat.h>
11 #include <time.h>
12
13 #include <sys/socket.h>
14 #include <arpa/inet.h>
15 #include <unistd.h>
16
17 #include <errno.h>
18
19 #include <tomcrypt.h>
20 #include "tlse.h"
21
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) {
28         int hash_idx;
29         unsigned long dlen = outlen;
30         unsigned char dummy_label[1] = { 0 };
31
32         if (!salt || salt_len == 0) {
33                 salt_len = 1;
34                 salt = dummy_label;
35         }
36
37         if (mac_length == TLS_SHA384_MAC_SIZE) {
38                 hash_idx = find_hash("sha384");
39                 dlen = mac_length;
40         } else {
41                 hash_idx = find_hash("sha256");
42         }
43
44         hmac_memory(hash_idx, salt, salt_len, ikm, ikm_len, output, &dlen);
45         return dlen;
46 }
47
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) {
53         int prefix_len;
54         *(unsigned short *) &hkdflabel[0] = htons(length);
55
56         if (prefix) {
57                 prefix_len = strlen(prefix);
58                 memcpy(&hkdflabel[3], prefix, prefix_len);
59         } else {
60                 memcpy(&hkdflabel[3], "tls13 ", 6);
61                 prefix_len = 6;
62         }
63
64         hkdflabel[2] = (unsigned char) prefix_len + label_len;
65
66         memcpy(&hkdflabel[3 + prefix_len], label, label_len);
67
68         hkdflabel[3 + prefix_len + label_len] = data_len;
69
70         if (data_len) {
71                 memcpy(&hkdflabel[4 + prefix_len + label_len], data,
72                        data_len);
73         }
74
75         return 4 + prefix_len + label_len + data_len;
76 }
77
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;
86         int hash_idx;
87         unsigned int i;
88         unsigned char i2 = 0;
89         unsigned int idx = 0;
90         hmac_state hmac;
91         unsigned int copylen;
92
93         if (mac_length == TLS_SHA384_MAC_SIZE) {
94                 hash_idx = find_hash("sha384");
95                 dlen = mac_length;
96         } else {
97                 hash_idx = find_hash("sha256");
98         }
99
100         while (outlen) {
101                 hmac_init(&hmac, hash_idx, secret, secret_len);
102                 if (i2) {
103                         hmac_process(&hmac, digest_out, dlen);
104                 }
105                 if (info && info_len) {
106                         hmac_process(&hmac, info, info_len);
107                 }
108                 i2++;
109                 hmac_process(&hmac, &i2, 1);
110                 hmac_done(&hmac, digest_out, &dlen);
111
112                 copylen = outlen;
113                 if (copylen > dlen) {
114                         copylen = (unsigned int) dlen;
115                 }
116
117                 for (i = 0; i < copylen; i++) {
118                         output[idx++] = digest_out[i];
119                         outlen--;
120                 }
121         }
122 }
123
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,
130                         outlen, NULL);
131         tls_hkdf_expand(mac_length, output, outlen, secret, secret_len,
132                         hkdf_label, len);
133 }