1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
69
70
71
72
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
101
102
103
104
108
109
114
115
116
117
121
122
126
130
131
132
133
137
138
142
143
144
145
146
147
148
152
153
154
158
159
160
164
165
167
168
172
173
174
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* ... */
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_HKDF_C)
#include <string.h>
#include "mbedtls/hkdf.h"
#include "mbedtls/platform_util.h"
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len )
{
int ret;
unsigned char prk[MBEDTLS_MD_MAX_SIZE];
ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
if( ret == 0 )
{
ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ),
info, info_len, okm, okm_len );
}if (ret == 0) { ... }
mbedtls_platform_zeroize( prk, sizeof( prk ) );
return( ret );
}mbedtls_hkdf (const mbedtls_md_info_t *md, const unsigned char *salt, size_t salt_len, const unsigned char *ikm, size_t ikm_len, const unsigned char *info, size_t info_len, unsigned char *okm, size_t okm_len) { ... }
int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
unsigned char *prk )
{
unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' };
if( salt == NULL )
{
size_t hash_len;
if( salt_len != 0 )
{
return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
}if (salt_len != 0) { ... }
hash_len = mbedtls_md_get_size( md );
if( hash_len == 0 )
{
return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
}if (hash_len == 0) { ... }
salt = null_salt;
salt_len = hash_len;
}if (salt == NULL) { ... }
return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) );
}mbedtls_hkdf_extract (const mbedtls_md_info_t *md, const unsigned char *salt, size_t salt_len, const unsigned char *ikm, size_t ikm_len, unsigned char *prk) { ... }
int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
size_t prk_len, const unsigned char *info,
size_t info_len, unsigned char *okm, size_t okm_len )
{
size_t hash_len;
size_t where = 0;
size_t n;
size_t t_len = 0;
size_t i;
int ret = 0;
mbedtls_md_context_t ctx;
unsigned char t[MBEDTLS_MD_MAX_SIZE];
if( okm == NULL )
{
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
}if (okm == NULL) { ... }
hash_len = mbedtls_md_get_size( md );
if( prk_len < hash_len || hash_len == 0 )
{
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
}if (prk_len < hash_len || hash_len == 0) { ... }
if( info == NULL )
{
info = (const unsigned char *) "";
info_len = 0;
}if (info == NULL) { ... }
n = okm_len / hash_len;
if( (okm_len % hash_len) != 0 )
{
n++;
}if ((okm_len % hash_len) != 0) { ... }
/* ... */
if( n > 255 )
{
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
}if (n > 255) { ... }
mbedtls_md_init( &ctx );
if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 )
{
goto exit;
}if ((ret = mbedtls_md_setup( &ctx, md, 1) ) != 0) { ... }
/* ... */
for( i = 1; i <= n; i++ )
{
size_t num_to_copy;
unsigned char c = i & 0xff;
ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len );
if( ret != 0 )
{
goto exit;
}if (ret != 0) { ... }
ret = mbedtls_md_hmac_update( &ctx, t, t_len );
if( ret != 0 )
{
goto exit;
}if (ret != 0) { ... }
ret = mbedtls_md_hmac_update( &ctx, info, info_len );
if( ret != 0 )
{
goto exit;
}if (ret != 0) { ... }
/* ... */
ret = mbedtls_md_hmac_update( &ctx, &c, 1 );
if( ret != 0 )
{
goto exit;
}if (ret != 0) { ... }
ret = mbedtls_md_hmac_finish( &ctx, t );
if( ret != 0 )
{
goto exit;
}if (ret != 0) { ... }
num_to_copy = i != n ? hash_len : okm_len - where;
memcpy( okm + where, t, num_to_copy );
where += hash_len;
t_len = hash_len;
}for (i = 1; i <= n; i++) { ... }
exit:
mbedtls_md_free( &ctx );
mbedtls_platform_zeroize( t, sizeof( t ) );
return( ret );
}mbedtls_hkdf_expand (const mbedtls_md_info_t *md, const unsigned char *prk, size_t prk_len, const unsigned char *info, size_t info_len, unsigned char *okm, size_t okm_len) { ... }
/* ... */
#endif