… | |
… | |
31 | |
31 | |
32 | #include "config.h" |
32 | #include "config.h" |
33 | |
33 | |
34 | #include <cstring> |
34 | #include <cstring> |
35 | |
35 | |
|
|
36 | #include <openssl/opensslv.h> |
36 | #include <openssl/rand.h> |
37 | #include <openssl/rand.h> |
37 | #include <openssl/hmac.h> |
38 | #include <openssl/hmac.h> |
38 | |
39 | |
39 | #include "util.h" |
40 | #include "util.h" |
40 | #include "hkdf.h" |
41 | #include "hkdf.h" |
|
|
42 | |
|
|
43 | // openssl 0.9.8 compatibility |
|
|
44 | #if OPENSSL_VERSION_NUMBER < 0x10100000 |
|
|
45 | #define require101(exp) exp |
|
|
46 | #else |
|
|
47 | #define require101(exp) equire (exp) |
|
|
48 | #endif |
41 | |
49 | |
42 | hkdf::hkdf (const void *salt, int len, const EVP_MD *xtr_hash) |
50 | hkdf::hkdf (const void *salt, int len, const EVP_MD *xtr_hash) |
43 | { |
51 | { |
44 | HMAC_CTX_init (&ctx); |
52 | HMAC_CTX_init (&ctx); |
45 | |
53 | |
… | |
… | |
48 | memset (prk, 0, sizeof prk); |
56 | memset (prk, 0, sizeof prk); |
49 | salt = prk; |
57 | salt = prk; |
50 | len = EVP_MD_size (xtr_hash); |
58 | len = EVP_MD_size (xtr_hash); |
51 | } |
59 | } |
52 | |
60 | |
53 | require (HMAC_Init_ex (&ctx, salt, len, xtr_hash, 0)); |
61 | require101 (HMAC_Init_ex (&ctx, salt, len, xtr_hash, 0)); |
54 | } |
62 | } |
55 | |
63 | |
56 | hkdf::~hkdf () |
64 | hkdf::~hkdf () |
57 | { |
65 | { |
58 | HMAC_CTX_cleanup (&ctx); |
66 | HMAC_CTX_cleanup (&ctx); |
59 | } |
67 | } |
60 | |
68 | |
61 | void |
69 | void |
62 | hkdf::extract (const void *ikm, int len) |
70 | hkdf::extract (const void *ikm, int len) |
63 | { |
71 | { |
64 | require (HMAC_Update (&ctx, (u8 *)ikm, len)); |
72 | require101 (HMAC_Update (&ctx, (u8 *)ikm, len)); |
65 | } |
73 | } |
66 | |
74 | |
67 | void |
75 | void |
68 | hkdf::extract_done (const EVP_MD *prf_hash) |
76 | hkdf::extract_done (const EVP_MD *prf_hash) |
69 | { |
77 | { |
70 | require (HMAC_Final (&ctx, prk, 0)); |
78 | require101 (HMAC_Final (&ctx, prk, 0)); |
71 | require (HMAC_Init_ex (&ctx, 0, 0, prf_hash, 0)); |
79 | require101 (HMAC_Init_ex (&ctx, 0, 0, prf_hash, 0)); |
72 | } |
80 | } |
73 | |
81 | |
74 | void |
82 | void |
75 | hkdf::expand (void *okm, int len, const void *info, int infolen) |
83 | hkdf::expand (void *okm, int len, const void *info, int infolen) |
76 | { |
84 | { |
… | |
… | |
78 | u8 iter = 0; |
86 | u8 iter = 0; |
79 | int md_size = HMAC_size (&ctx); |
87 | int md_size = HMAC_size (&ctx); |
80 | |
88 | |
81 | while (len) |
89 | while (len) |
82 | { |
90 | { |
83 | require (HMAC_Init_ex (&ctx, prk, md_size, 0, 0)); |
91 | require101 (HMAC_Init_ex (&ctx, prk, md_size, 0, 0)); |
84 | |
92 | |
85 | if (iter) |
93 | if (iter) |
86 | require (HMAC_Update (&ctx, tn, md_size)); |
94 | require101 (HMAC_Update (&ctx, tn, md_size)); |
87 | |
95 | |
88 | require (HMAC_Update (&ctx, (u8 *)info, infolen)); |
96 | require101 (HMAC_Update (&ctx, (u8 *)info, infolen)); |
89 | |
|
|
90 | |
97 | |
91 | ++iter; |
98 | ++iter; |
92 | require (iter); |
99 | require (iter); |
93 | |
100 | |
94 | require (HMAC_Update (&ctx, &iter, 1)); |
101 | require101 (HMAC_Update (&ctx, &iter, 1)); |
95 | |
102 | |
96 | require (HMAC_Final (&ctx, tn, 0)); |
103 | require101 (HMAC_Final (&ctx, tn, 0)); |
97 | |
104 | |
98 | int ol = len > md_size ? md_size : len; |
105 | int ol = len > md_size ? md_size : len; |
99 | |
106 | |
100 | memcpy (okm, tn, ol); |
107 | memcpy (okm, tn, ol); |
101 | |
108 | |