1/* 2 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10#include <stdlib.h> 11#include <string.h> 12#include <openssl/hmac.h> 13#include <openssl/kdf.h> 14#include <openssl/evp.h> 15#include "internal/cryptlib.h" 16#include "crypto/evp.h" 17 18#define HKDF_MAXBUF 1024 19 20static unsigned char *HKDF(const EVP_MD *evp_md, 21 const unsigned char *salt, size_t salt_len, 22 const unsigned char *key, size_t key_len, 23 const unsigned char *info, size_t info_len, 24 unsigned char *okm, size_t okm_len); 25 26static unsigned char *HKDF_Extract(const EVP_MD *evp_md, 27 const unsigned char *salt, size_t salt_len, 28 const unsigned char *key, size_t key_len, 29 unsigned char *prk, size_t *prk_len); 30 31static unsigned char *HKDF_Expand(const EVP_MD *evp_md, 32 const unsigned char *prk, size_t prk_len, 33 const unsigned char *info, size_t info_len, 34 unsigned char *okm, size_t okm_len); 35 36typedef struct { 37 int mode; 38 const EVP_MD *md; 39 unsigned char *salt; 40 size_t salt_len; 41 unsigned char *key; 42 size_t key_len; 43 unsigned char info[HKDF_MAXBUF]; 44 size_t info_len; 45} HKDF_PKEY_CTX; 46 47static int pkey_hkdf_init(EVP_PKEY_CTX *ctx) 48{ 49 HKDF_PKEY_CTX *kctx; 50 51 if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) { 52 KDFerr(KDF_F_PKEY_HKDF_INIT, ERR_R_MALLOC_FAILURE); 53 return 0; 54 } 55 56 ctx->data = kctx; 57 58 return 1; 59} 60 61static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx) 62{ 63 HKDF_PKEY_CTX *kctx = ctx->data; 64 OPENSSL_clear_free(kctx->salt, kctx->salt_len); 65 OPENSSL_clear_free(kctx->key, kctx->key_len); 66 OPENSSL_cleanse(kctx->info, kctx->info_len); 67 OPENSSL_free(kctx); 68} 69 70static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 71{ 72 HKDF_PKEY_CTX *kctx = ctx->data; 73 74 switch (type) { 75 case EVP_PKEY_CTRL_HKDF_MD: 76 if (p2 == NULL) 77 return 0; 78 79 kctx->md = p2; 80 return 1; 81 82 case EVP_PKEY_CTRL_HKDF_MODE: 83 kctx->mode = p1; 84 return 1; 85 86 case EVP_PKEY_CTRL_HKDF_SALT: 87 if (p1 == 0 || p2 == NULL) 88 return 1; 89 90 if (p1 < 0) 91 return 0; 92 93 if (kctx->salt != NULL) 94 OPENSSL_clear_free(kctx->salt, kctx->salt_len); 95 96 kctx->salt = OPENSSL_memdup(p2, p1); 97 if (kctx->salt == NULL) 98 return 0; 99 100 kctx->salt_len = p1; 101 return 1; 102 103 case EVP_PKEY_CTRL_HKDF_KEY: 104 if (p1 < 0) 105 return 0; 106 107 if (kctx->key != NULL) 108 OPENSSL_clear_free(kctx->key, kctx->key_len); 109 110 kctx->key = OPENSSL_memdup(p2, p1); 111 if (kctx->key == NULL) 112 return 0; 113 114 kctx->key_len = p1; 115 return 1; 116 117 case EVP_PKEY_CTRL_HKDF_INFO: 118 if (p1 == 0 || p2 == NULL) 119 return 1; 120 121 if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len)) 122 return 0; 123 124 memcpy(kctx->info + kctx->info_len, p2, p1); 125 kctx->info_len += p1; 126 return 1; 127 128 default: 129 return -2; 130 131 } 132} 133 134static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, 135 const char *value) 136{ 137 if (strcmp(type, "mode") == 0) { 138 int mode; 139 140 if (strcmp(value, "EXTRACT_AND_EXPAND") == 0) 141 mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND; 142 else if (strcmp(value, "EXTRACT_ONLY") == 0) 143 mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY; 144 else if (strcmp(value, "EXPAND_ONLY") == 0) 145 mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; 146 else 147 return 0; 148 149 return EVP_PKEY_CTX_hkdf_mode(ctx, mode); 150 } 151 152 if (strcmp(type, "md") == 0) 153 return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE, 154 EVP_PKEY_CTRL_HKDF_MD, value); 155 156 if (strcmp(type, "salt") == 0) 157 return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); 158 159 if (strcmp(type, "hexsalt") == 0) 160 return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); 161 162 if (strcmp(type, "key") == 0) 163 return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); 164 165 if (strcmp(type, "hexkey") == 0) 166 return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); 167 168 if (strcmp(type, "info") == 0) 169 return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); 170 171 if (strcmp(type, "hexinfo") == 0) 172 return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); 173 174 KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); 175 return -2; 176} 177 178static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx) 179{ 180 HKDF_PKEY_CTX *kctx = ctx->data; 181 182 OPENSSL_clear_free(kctx->key, kctx->key_len); 183 OPENSSL_clear_free(kctx->salt, kctx->salt_len); 184 OPENSSL_cleanse(kctx->info, kctx->info_len); 185 memset(kctx, 0, sizeof(*kctx)); 186 187 return 1; 188} 189 190static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, 191 size_t *keylen) 192{ 193 HKDF_PKEY_CTX *kctx = ctx->data; 194 195 if (kctx->md == NULL) { 196 KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); 197 return 0; 198 } 199 if (kctx->key == NULL) { 200 KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY); 201 return 0; 202 } 203 204 switch (kctx->mode) { 205 case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: 206 return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key, 207 kctx->key_len, kctx->info, kctx->info_len, key, 208 *keylen) != NULL; 209 210 case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: 211 if (key == NULL) { 212 *keylen = EVP_MD_size(kctx->md); 213 return 1; 214 } 215 return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key, 216 kctx->key_len, key, keylen) != NULL; 217 218 case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: 219 return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info, 220 kctx->info_len, key, *keylen) != NULL; 221 222 default: 223 return 0; 224 } 225} 226 227const EVP_PKEY_METHOD hkdf_pkey_meth = { 228 EVP_PKEY_HKDF, 229 0, 230 pkey_hkdf_init, 231 0, 232 pkey_hkdf_cleanup, 233 234 0, 0, 235 0, 0, 236 237 0, 238 0, 239 240 0, 241 0, 242 243 0, 0, 244 245 0, 0, 0, 0, 246 247 0, 0, 248 249 0, 0, 250 251 pkey_hkdf_derive_init, 252 pkey_hkdf_derive, 253 pkey_hkdf_ctrl, 254 pkey_hkdf_ctrl_str 255}; 256 257static unsigned char *HKDF(const EVP_MD *evp_md, 258 const unsigned char *salt, size_t salt_len, 259 const unsigned char *key, size_t key_len, 260 const unsigned char *info, size_t info_len, 261 unsigned char *okm, size_t okm_len) 262{ 263 unsigned char prk[EVP_MAX_MD_SIZE]; 264 unsigned char *ret; 265 size_t prk_len; 266 267 if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len)) 268 return NULL; 269 270 ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len); 271 OPENSSL_cleanse(prk, sizeof(prk)); 272 273 return ret; 274} 275 276static unsigned char *HKDF_Extract(const EVP_MD *evp_md, 277 const unsigned char *salt, size_t salt_len, 278 const unsigned char *key, size_t key_len, 279 unsigned char *prk, size_t *prk_len) 280{ 281 unsigned int tmp_len; 282 283 if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len)) 284 return NULL; 285 286 *prk_len = tmp_len; 287 return prk; 288} 289 290static unsigned char *HKDF_Expand(const EVP_MD *evp_md, 291 const unsigned char *prk, size_t prk_len, 292 const unsigned char *info, size_t info_len, 293 unsigned char *okm, size_t okm_len) 294{ 295 HMAC_CTX *hmac; 296 unsigned char *ret = NULL; 297 298 unsigned int i; 299 300 unsigned char prev[EVP_MAX_MD_SIZE]; 301 302 size_t done_len = 0, dig_len = EVP_MD_size(evp_md); 303 304 size_t n = okm_len / dig_len; 305 if (okm_len % dig_len) 306 n++; 307 308 if (n > 255 || okm == NULL) 309 return NULL; 310 311 if ((hmac = HMAC_CTX_new()) == NULL) 312 return NULL; 313 314 if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL)) 315 goto err; 316 317 for (i = 1; i <= n; i++) { 318 size_t copy_len; 319 const unsigned char ctr = i; 320 321 if (i > 1) { 322 if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL)) 323 goto err; 324 325 if (!HMAC_Update(hmac, prev, dig_len)) 326 goto err; 327 } 328 329 if (!HMAC_Update(hmac, info, info_len)) 330 goto err; 331 332 if (!HMAC_Update(hmac, &ctr, 1)) 333 goto err; 334 335 if (!HMAC_Final(hmac, prev, NULL)) 336 goto err; 337 338 copy_len = (done_len + dig_len > okm_len) ? 339 okm_len - done_len : 340 dig_len; 341 342 memcpy(okm + done_len, prev, copy_len); 343 344 done_len += copy_len; 345 } 346 ret = okm; 347 348 err: 349 OPENSSL_cleanse(prev, sizeof(prev)); 350 HMAC_CTX_free(hmac); 351 return ret; 352} 353