A local copy of OpenSSL from GitHub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

488 lines
15 KiB

  1. /*
  2. * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (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. * HMAC low level APIs are deprecated for public use, but still ok for internal
  11. * use.
  12. */
  13. #include "internal/deprecated.h"
  14. #include <stdlib.h>
  15. #include <stdarg.h>
  16. #include <string.h>
  17. #include <openssl/hmac.h>
  18. #include <openssl/evp.h>
  19. #include <openssl/kdf.h>
  20. #include <openssl/core_names.h>
  21. #include <openssl/proverr.h>
  22. #include "internal/cryptlib.h"
  23. #include "internal/numbers.h"
  24. #include "crypto/evp.h"
  25. #include "prov/provider_ctx.h"
  26. #include "prov/providercommon.h"
  27. #include "prov/implementations.h"
  28. #include "prov/provider_util.h"
  29. #include "e_os.h"
  30. #define HKDF_MAXBUF 1024
  31. static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_new;
  32. static OSSL_FUNC_kdf_freectx_fn kdf_hkdf_free;
  33. static OSSL_FUNC_kdf_reset_fn kdf_hkdf_reset;
  34. static OSSL_FUNC_kdf_derive_fn kdf_hkdf_derive;
  35. static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;
  36. static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params;
  37. static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
  38. static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;
  39. static int HKDF(const EVP_MD *evp_md,
  40. const unsigned char *salt, size_t salt_len,
  41. const unsigned char *key, size_t key_len,
  42. const unsigned char *info, size_t info_len,
  43. unsigned char *okm, size_t okm_len);
  44. static int HKDF_Extract(const EVP_MD *evp_md,
  45. const unsigned char *salt, size_t salt_len,
  46. const unsigned char *ikm, size_t ikm_len,
  47. unsigned char *prk, size_t prk_len);
  48. static int HKDF_Expand(const EVP_MD *evp_md,
  49. const unsigned char *prk, size_t prk_len,
  50. const unsigned char *info, size_t info_len,
  51. unsigned char *okm, size_t okm_len);
  52. typedef struct {
  53. void *provctx;
  54. int mode;
  55. PROV_DIGEST digest;
  56. unsigned char *salt;
  57. size_t salt_len;
  58. unsigned char *key;
  59. size_t key_len;
  60. unsigned char info[HKDF_MAXBUF];
  61. size_t info_len;
  62. } KDF_HKDF;
  63. static void *kdf_hkdf_new(void *provctx)
  64. {
  65. KDF_HKDF *ctx;
  66. if (!ossl_prov_is_running())
  67. return NULL;
  68. if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
  69. ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
  70. else
  71. ctx->provctx = provctx;
  72. return ctx;
  73. }
  74. static void kdf_hkdf_free(void *vctx)
  75. {
  76. KDF_HKDF *ctx = (KDF_HKDF *)vctx;
  77. if (ctx != NULL) {
  78. kdf_hkdf_reset(ctx);
  79. OPENSSL_free(ctx);
  80. }
  81. }
  82. static void kdf_hkdf_reset(void *vctx)
  83. {
  84. KDF_HKDF *ctx = (KDF_HKDF *)vctx;
  85. void *provctx = ctx->provctx;
  86. ossl_prov_digest_reset(&ctx->digest);
  87. OPENSSL_free(ctx->salt);
  88. OPENSSL_clear_free(ctx->key, ctx->key_len);
  89. OPENSSL_cleanse(ctx->info, ctx->info_len);
  90. memset(ctx, 0, sizeof(*ctx));
  91. ctx->provctx = provctx;
  92. }
  93. static size_t kdf_hkdf_size(KDF_HKDF *ctx)
  94. {
  95. int sz;
  96. const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
  97. if (ctx->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY)
  98. return SIZE_MAX;
  99. if (md == NULL) {
  100. ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
  101. return 0;
  102. }
  103. sz = EVP_MD_size(md);
  104. if (sz < 0)
  105. return 0;
  106. return sz;
  107. }
  108. static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
  109. const OSSL_PARAM params[])
  110. {
  111. KDF_HKDF *ctx = (KDF_HKDF *)vctx;
  112. const EVP_MD *md;
  113. if (!ossl_prov_is_running() || !kdf_hkdf_set_ctx_params(ctx, params))
  114. return 0;
  115. md = ossl_prov_digest_md(&ctx->digest);
  116. if (md == NULL) {
  117. ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
  118. return 0;
  119. }
  120. if (ctx->key == NULL) {
  121. ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
  122. return 0;
  123. }
  124. if (keylen == 0) {
  125. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
  126. return 0;
  127. }
  128. switch (ctx->mode) {
  129. case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
  130. return HKDF(md, ctx->salt, ctx->salt_len, ctx->key,
  131. ctx->key_len, ctx->info, ctx->info_len, key,
  132. keylen);
  133. case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
  134. return HKDF_Extract(md, ctx->salt, ctx->salt_len, ctx->key,
  135. ctx->key_len, key, keylen);
  136. case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
  137. return HKDF_Expand(md, ctx->key, ctx->key_len, ctx->info,
  138. ctx->info_len, key, keylen);
  139. default:
  140. return 0;
  141. }
  142. }
  143. static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
  144. {
  145. const OSSL_PARAM *p;
  146. KDF_HKDF *ctx = vctx;
  147. OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx);
  148. int n;
  149. if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
  150. return 0;
  151. if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) {
  152. if (p->data_type == OSSL_PARAM_UTF8_STRING) {
  153. if (strcasecmp(p->data, "EXTRACT_AND_EXPAND") == 0) {
  154. ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;
  155. } else if (strcasecmp(p->data, "EXTRACT_ONLY") == 0) {
  156. ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
  157. } else if (strcasecmp(p->data, "EXPAND_ONLY") == 0) {
  158. ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
  159. } else {
  160. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
  161. return 0;
  162. }
  163. } else if (OSSL_PARAM_get_int(p, &n)) {
  164. if (n != EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND
  165. && n != EVP_KDF_HKDF_MODE_EXTRACT_ONLY
  166. && n != EVP_KDF_HKDF_MODE_EXPAND_ONLY) {
  167. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
  168. return 0;
  169. }
  170. ctx->mode = n;
  171. } else {
  172. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
  173. return 0;
  174. }
  175. }
  176. if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) {
  177. OPENSSL_clear_free(ctx->key, ctx->key_len);
  178. ctx->key = NULL;
  179. if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->key, 0,
  180. &ctx->key_len))
  181. return 0;
  182. }
  183. if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
  184. if (p->data_size != 0 && p->data != NULL) {
  185. OPENSSL_free(ctx->salt);
  186. ctx->salt = NULL;
  187. if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
  188. &ctx->salt_len))
  189. return 0;
  190. }
  191. }
  192. /* The info fields concatenate, so process them all */
  193. if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) {
  194. ctx->info_len = 0;
  195. for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1,
  196. OSSL_KDF_PARAM_INFO)) {
  197. const void *q = ctx->info + ctx->info_len;
  198. size_t sz = 0;
  199. if (p->data_size != 0
  200. && p->data != NULL
  201. && !OSSL_PARAM_get_octet_string(p, (void **)&q,
  202. HKDF_MAXBUF - ctx->info_len,
  203. &sz))
  204. return 0;
  205. ctx->info_len += sz;
  206. }
  207. }
  208. return 1;
  209. }
  210. static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *ctx,
  211. ossl_unused void *provctx)
  212. {
  213. static const OSSL_PARAM known_settable_ctx_params[] = {
  214. OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0),
  215. OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL),
  216. OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
  217. OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
  218. OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
  219. OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
  220. OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
  221. OSSL_PARAM_END
  222. };
  223. return known_settable_ctx_params;
  224. }
  225. static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
  226. {
  227. KDF_HKDF *ctx = (KDF_HKDF *)vctx;
  228. OSSL_PARAM *p;
  229. if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
  230. return OSSL_PARAM_set_size_t(p, kdf_hkdf_size(ctx));
  231. return -2;
  232. }
  233. static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
  234. ossl_unused void *provctx)
  235. {
  236. static const OSSL_PARAM known_gettable_ctx_params[] = {
  237. OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
  238. OSSL_PARAM_END
  239. };
  240. return known_gettable_ctx_params;
  241. }
  242. const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = {
  243. { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new },
  244. { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free },
  245. { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset },
  246. { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_hkdf_derive },
  247. { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
  248. (void(*)(void))kdf_hkdf_settable_ctx_params },
  249. { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_hkdf_set_ctx_params },
  250. { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
  251. (void(*)(void))kdf_hkdf_gettable_ctx_params },
  252. { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params },
  253. { 0, NULL }
  254. };
  255. /*
  256. * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
  257. * Section 2 (https://tools.ietf.org/html/rfc5869#section-2) and
  258. * "Cryptographic Extraction and Key Derivation: The HKDF Scheme"
  259. * Section 4.2 (https://eprint.iacr.org/2010/264.pdf).
  260. *
  261. * From the paper:
  262. * The scheme HKDF is specified as:
  263. * HKDF(XTS, SKM, CTXinfo, L) = K(1) | K(2) | ... | K(t)
  264. *
  265. * where:
  266. * SKM is source key material
  267. * XTS is extractor salt (which may be null or constant)
  268. * CTXinfo is context information (may be null)
  269. * L is the number of key bits to be produced by KDF
  270. * k is the output length in bits of the hash function used with HMAC
  271. * t = ceil(L/k)
  272. * the value K(t) is truncated to its first d = L mod k bits.
  273. *
  274. * From RFC 5869:
  275. * 2.2. Step 1: Extract
  276. * HKDF-Extract(salt, IKM) -> PRK
  277. * 2.3. Step 2: Expand
  278. * HKDF-Expand(PRK, info, L) -> OKM
  279. */
  280. static int HKDF(const EVP_MD *evp_md,
  281. const unsigned char *salt, size_t salt_len,
  282. const unsigned char *ikm, size_t ikm_len,
  283. const unsigned char *info, size_t info_len,
  284. unsigned char *okm, size_t okm_len)
  285. {
  286. unsigned char prk[EVP_MAX_MD_SIZE];
  287. int ret, sz;
  288. size_t prk_len;
  289. sz = EVP_MD_size(evp_md);
  290. if (sz < 0)
  291. return 0;
  292. prk_len = (size_t)sz;
  293. /* Step 1: HKDF-Extract(salt, IKM) -> PRK */
  294. if (!HKDF_Extract(evp_md, salt, salt_len, ikm, ikm_len, prk, prk_len))
  295. return 0;
  296. /* Step 2: HKDF-Expand(PRK, info, L) -> OKM */
  297. ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
  298. OPENSSL_cleanse(prk, sizeof(prk));
  299. return ret;
  300. }
  301. /*
  302. * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
  303. * Section 2.2 (https://tools.ietf.org/html/rfc5869#section-2.2).
  304. *
  305. * 2.2. Step 1: Extract
  306. *
  307. * HKDF-Extract(salt, IKM) -> PRK
  308. *
  309. * Options:
  310. * Hash a hash function; HashLen denotes the length of the
  311. * hash function output in octets
  312. *
  313. * Inputs:
  314. * salt optional salt value (a non-secret random value);
  315. * if not provided, it is set to a string of HashLen zeros.
  316. * IKM input keying material
  317. *
  318. * Output:
  319. * PRK a pseudorandom key (of HashLen octets)
  320. *
  321. * The output PRK is calculated as follows:
  322. *
  323. * PRK = HMAC-Hash(salt, IKM)
  324. */
  325. static int HKDF_Extract(const EVP_MD *evp_md,
  326. const unsigned char *salt, size_t salt_len,
  327. const unsigned char *ikm, size_t ikm_len,
  328. unsigned char *prk, size_t prk_len)
  329. {
  330. int sz = EVP_MD_size(evp_md);
  331. if (sz < 0)
  332. return 0;
  333. if (prk_len != (size_t)sz) {
  334. ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE);
  335. return 0;
  336. }
  337. /* calc: PRK = HMAC-Hash(salt, IKM) */
  338. return HMAC(evp_md, salt, salt_len, ikm, ikm_len, prk, NULL) != NULL;
  339. }
  340. /*
  341. * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
  342. * Section 2.3 (https://tools.ietf.org/html/rfc5869#section-2.3).
  343. *
  344. * 2.3. Step 2: Expand
  345. *
  346. * HKDF-Expand(PRK, info, L) -> OKM
  347. *
  348. * Options:
  349. * Hash a hash function; HashLen denotes the length of the
  350. * hash function output in octets
  351. *
  352. * Inputs:
  353. * PRK a pseudorandom key of at least HashLen octets
  354. * (usually, the output from the extract step)
  355. * info optional context and application specific information
  356. * (can be a zero-length string)
  357. * L length of output keying material in octets
  358. * (<= 255*HashLen)
  359. *
  360. * Output:
  361. * OKM output keying material (of L octets)
  362. *
  363. * The output OKM is calculated as follows:
  364. *
  365. * N = ceil(L/HashLen)
  366. * T = T(1) | T(2) | T(3) | ... | T(N)
  367. * OKM = first L octets of T
  368. *
  369. * where:
  370. * T(0) = empty string (zero length)
  371. * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
  372. * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
  373. * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
  374. * ...
  375. *
  376. * (where the constant concatenated to the end of each T(n) is a
  377. * single octet.)
  378. */
  379. static int HKDF_Expand(const EVP_MD *evp_md,
  380. const unsigned char *prk, size_t prk_len,
  381. const unsigned char *info, size_t info_len,
  382. unsigned char *okm, size_t okm_len)
  383. {
  384. HMAC_CTX *hmac;
  385. int ret = 0, sz;
  386. unsigned int i;
  387. unsigned char prev[EVP_MAX_MD_SIZE];
  388. size_t done_len = 0, dig_len, n;
  389. sz = EVP_MD_size(evp_md);
  390. if (sz <= 0)
  391. return 0;
  392. dig_len = (size_t)sz;
  393. /* calc: N = ceil(L/HashLen) */
  394. n = okm_len / dig_len;
  395. if (okm_len % dig_len)
  396. n++;
  397. if (n > 255 || okm == NULL)
  398. return 0;
  399. if ((hmac = HMAC_CTX_new()) == NULL)
  400. return 0;
  401. if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
  402. goto err;
  403. for (i = 1; i <= n; i++) {
  404. size_t copy_len;
  405. const unsigned char ctr = i;
  406. /* calc: T(i) = HMAC-Hash(PRK, T(i - 1) | info | i) */
  407. if (i > 1) {
  408. if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
  409. goto err;
  410. if (!HMAC_Update(hmac, prev, dig_len))
  411. goto err;
  412. }
  413. if (!HMAC_Update(hmac, info, info_len))
  414. goto err;
  415. if (!HMAC_Update(hmac, &ctr, 1))
  416. goto err;
  417. if (!HMAC_Final(hmac, prev, NULL))
  418. goto err;
  419. copy_len = (done_len + dig_len > okm_len) ?
  420. okm_len - done_len :
  421. dig_len;
  422. memcpy(okm + done_len, prev, copy_len);
  423. done_len += copy_len;
  424. }
  425. ret = 1;
  426. err:
  427. OPENSSL_cleanse(prev, sizeof(prev));
  428. HMAC_CTX_free(hmac);
  429. return ret;
  430. }