1/* BEGIN_HEADER */
2#include "mbedtls/hkdf.h"
3#include "mbedtls/md_internal.h"
4/* END_HEADER */
5
6/* BEGIN_DEPENDENCIES
7 * depends_on:MBEDTLS_HKDF_C
8 * END_DEPENDENCIES
9 */
10
11/* BEGIN_CASE */
12void test_hkdf( int md_alg, data_t *ikm, data_t *salt, data_t *info,
13                data_t *expected_okm )
14{
15    int ret;
16    unsigned char okm[128] = { '\0' };
17
18    const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
19    TEST_ASSERT( md != NULL );
20
21    TEST_ASSERT( expected_okm->len <= sizeof( okm ) );
22
23    ret = mbedtls_hkdf( md, salt->x, salt->len, ikm->x, ikm->len,
24                        info->x, info->len, okm, expected_okm->len );
25    TEST_ASSERT( ret == 0 );
26
27    ASSERT_COMPARE( okm            , expected_okm->len,
28                    expected_okm->x, expected_okm->len );
29}
30/* END_CASE */
31
32/* BEGIN_CASE */
33void test_hkdf_extract( int md_alg, char *hex_ikm_string,
34                        char *hex_salt_string, char *hex_prk_string )
35{
36    int ret;
37    unsigned char *ikm = NULL;
38    unsigned char *salt = NULL;
39    unsigned char *prk = NULL;
40    unsigned char *output_prk = NULL;
41    size_t ikm_len, salt_len, prk_len, output_prk_len;
42
43    const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
44    TEST_ASSERT( md != NULL );
45
46    output_prk_len = mbedtls_md_get_size( md );
47    output_prk = mbedtls_calloc( 1, output_prk_len );
48
49    ikm = mbedtls_test_unhexify_alloc( hex_ikm_string, &ikm_len );
50    salt = mbedtls_test_unhexify_alloc( hex_salt_string, &salt_len );
51    prk = mbedtls_test_unhexify_alloc( hex_prk_string, &prk_len );
52
53    ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, output_prk );
54    TEST_ASSERT( ret == 0 );
55
56    ASSERT_COMPARE( output_prk, output_prk_len, prk, prk_len );
57
58exit:
59    mbedtls_free(ikm);
60    mbedtls_free(salt);
61    mbedtls_free(prk);
62    mbedtls_free(output_prk);
63}
64/* END_CASE */
65
66/* BEGIN_CASE */
67void test_hkdf_expand( int md_alg, char *hex_info_string,
68                       char *hex_prk_string, char *hex_okm_string )
69{
70    enum { OKM_LEN  = 1024 };
71    int ret;
72    unsigned char *info = NULL;
73    unsigned char *prk = NULL;
74    unsigned char *okm = NULL;
75    unsigned char *output_okm = NULL;
76    size_t info_len, prk_len, okm_len;
77
78    const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
79    TEST_ASSERT( md != NULL );
80
81    output_okm = mbedtls_calloc( OKM_LEN, 1 );
82
83    prk = mbedtls_test_unhexify_alloc( hex_prk_string, &prk_len );
84    info = mbedtls_test_unhexify_alloc( hex_info_string, &info_len );
85    okm = mbedtls_test_unhexify_alloc( hex_okm_string, &okm_len );
86    TEST_ASSERT( prk_len == mbedtls_md_get_size( md ) );
87    TEST_ASSERT( okm_len < OKM_LEN );
88
89    ret = mbedtls_hkdf_expand( md, prk, prk_len, info, info_len,
90                               output_okm, OKM_LEN );
91    TEST_ASSERT( ret == 0 );
92    ASSERT_COMPARE( output_okm, okm_len, okm, okm_len );
93
94exit:
95    mbedtls_free(info);
96    mbedtls_free(prk);
97    mbedtls_free(okm);
98    mbedtls_free(output_okm);
99}
100/* END_CASE */
101
102/* BEGIN_CASE */
103void test_hkdf_extract_ret( int hash_len, int ret )
104{
105    int output_ret;
106    unsigned char *salt = NULL;
107    unsigned char *ikm = NULL;
108    unsigned char *prk = NULL;
109    size_t salt_len, ikm_len;
110    struct mbedtls_md_info_t fake_md_info;
111
112    memset( &fake_md_info, 0, sizeof( fake_md_info ) );
113    fake_md_info.type = MBEDTLS_MD_NONE;
114    fake_md_info.size = hash_len;
115
116    prk = mbedtls_calloc( MBEDTLS_MD_MAX_SIZE, 1 );
117    salt_len = 0;
118    ikm_len = 0;
119
120    output_ret = mbedtls_hkdf_extract( &fake_md_info, salt, salt_len,
121                                       ikm, ikm_len, prk );
122    TEST_ASSERT( output_ret == ret );
123
124exit:
125    mbedtls_free(prk);
126}
127/* END_CASE */
128
129/* BEGIN_CASE */
130void test_hkdf_expand_ret( int hash_len, int prk_len, int okm_len, int ret )
131{
132    int output_ret;
133    unsigned char *info = NULL;
134    unsigned char *prk = NULL;
135    unsigned char *okm = NULL;
136    size_t info_len;
137    struct mbedtls_md_info_t fake_md_info;
138
139    memset( &fake_md_info, 0, sizeof( fake_md_info ) );
140    fake_md_info.type = MBEDTLS_MD_NONE;
141    fake_md_info.size = hash_len;
142
143    info_len = 0;
144
145    if (prk_len > 0)
146        prk = mbedtls_calloc( prk_len, 1 );
147
148    if (okm_len > 0)
149        okm = mbedtls_calloc( okm_len, 1 );
150
151    output_ret = mbedtls_hkdf_expand( &fake_md_info, prk, prk_len,
152                                      info, info_len, okm, okm_len );
153    TEST_ASSERT( output_ret == ret );
154
155exit:
156    mbedtls_free(prk);
157    mbedtls_free(okm);
158}
159/* END_CASE */
160