LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - hkdf.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 60.9 % 64 39
Test Date: 2025-06-29 08:09:00 Functions: 66.7 % 3 2

            Line data    Source code
       1              : /*
       2              :  *  HKDF implementation -- RFC 5869
       3              :  *
       4              :  *  Copyright The Mbed TLS Contributors
       5              :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       6              :  */
       7              : #include "common.h"
       8              : 
       9              : #if defined(MBEDTLS_HKDF_C)
      10              : 
      11              : #include <string.h>
      12              : #include "mbedtls/hkdf.h"
      13              : #include "mbedtls/platform_util.h"
      14              : #include "mbedtls/error.h"
      15              : 
      16            0 : int mbedtls_hkdf(const mbedtls_md_info_t *md, const unsigned char *salt,
      17              :                  size_t salt_len, const unsigned char *ikm, size_t ikm_len,
      18              :                  const unsigned char *info, size_t info_len,
      19              :                  unsigned char *okm, size_t okm_len)
      20              : {
      21            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
      22              :     unsigned char prk[MBEDTLS_MD_MAX_SIZE];
      23              : 
      24            0 :     ret = mbedtls_hkdf_extract(md, salt, salt_len, ikm, ikm_len, prk);
      25              : 
      26            0 :     if (ret == 0) {
      27            0 :         ret = mbedtls_hkdf_expand(md, prk, mbedtls_md_get_size(md),
      28              :                                   info, info_len, okm, okm_len);
      29              :     }
      30              : 
      31            0 :     mbedtls_platform_zeroize(prk, sizeof(prk));
      32              : 
      33            0 :     return ret;
      34              : }
      35              : 
      36          190 : int mbedtls_hkdf_extract(const mbedtls_md_info_t *md,
      37              :                          const unsigned char *salt, size_t salt_len,
      38              :                          const unsigned char *ikm, size_t ikm_len,
      39              :                          unsigned char *prk)
      40              : {
      41          190 :     unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' };
      42              : 
      43          190 :     if (salt == NULL) {
      44              :         size_t hash_len;
      45              : 
      46            0 :         if (salt_len != 0) {
      47            0 :             return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
      48              :         }
      49              : 
      50            0 :         hash_len = mbedtls_md_get_size(md);
      51              : 
      52            0 :         if (hash_len == 0) {
      53            0 :             return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
      54              :         }
      55              : 
      56            0 :         salt = null_salt;
      57            0 :         salt_len = hash_len;
      58              :     }
      59              : 
      60          190 :     return mbedtls_md_hmac(md, salt, salt_len, ikm, ikm_len, prk);
      61              : }
      62              : 
      63         1235 : int mbedtls_hkdf_expand(const mbedtls_md_info_t *md, const unsigned char *prk,
      64              :                         size_t prk_len, const unsigned char *info,
      65              :                         size_t info_len, unsigned char *okm, size_t okm_len)
      66              : {
      67              :     size_t hash_len;
      68         1235 :     size_t where = 0;
      69              :     size_t n;
      70         1235 :     size_t t_len = 0;
      71              :     size_t i;
      72         1235 :     int ret = 0;
      73              :     mbedtls_md_context_t ctx;
      74              :     unsigned char t[MBEDTLS_MD_MAX_SIZE];
      75              : 
      76         1235 :     if (okm == NULL) {
      77            0 :         return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
      78              :     }
      79              : 
      80         1235 :     hash_len = mbedtls_md_get_size(md);
      81              : 
      82         1235 :     if (prk_len < hash_len || hash_len == 0) {
      83            0 :         return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
      84              :     }
      85              : 
      86         1235 :     if (info == NULL) {
      87            0 :         info = (const unsigned char *) "";
      88            0 :         info_len = 0;
      89              :     }
      90              : 
      91         1235 :     n = okm_len / hash_len;
      92              : 
      93         1235 :     if (okm_len % hash_len != 0) {
      94          281 :         n++;
      95              :     }
      96              : 
      97              :     /*
      98              :      * Per RFC 5869 Section 2.3, okm_len must not exceed
      99              :      * 255 times the hash length
     100              :      */
     101         1235 :     if (n > 255) {
     102            0 :         return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
     103              :     }
     104              : 
     105         1235 :     mbedtls_md_init(&ctx);
     106              : 
     107         1235 :     if ((ret = mbedtls_md_setup(&ctx, md, 1)) != 0) {
     108            0 :         goto exit;
     109              :     }
     110              : 
     111         1235 :     memset(t, 0, hash_len);
     112              : 
     113              :     /*
     114              :      * Compute T = T(1) | T(2) | T(3) | ... | T(N)
     115              :      * Where T(N) is defined in RFC 5869 Section 2.3
     116              :      */
     117         2506 :     for (i = 1; i <= n; i++) {
     118              :         size_t num_to_copy;
     119         1271 :         unsigned char c = i & 0xff;
     120              : 
     121         1271 :         ret = mbedtls_md_hmac_starts(&ctx, prk, prk_len);
     122         1271 :         if (ret != 0) {
     123            0 :             goto exit;
     124              :         }
     125              : 
     126         1271 :         ret = mbedtls_md_hmac_update(&ctx, t, t_len);
     127         1271 :         if (ret != 0) {
     128            0 :             goto exit;
     129              :         }
     130              : 
     131         1271 :         ret = mbedtls_md_hmac_update(&ctx, info, info_len);
     132         1271 :         if (ret != 0) {
     133            0 :             goto exit;
     134              :         }
     135              : 
     136              :         /* The constant concatenated to the end of each T(n) is a single octet.
     137              :          * */
     138         1271 :         ret = mbedtls_md_hmac_update(&ctx, &c, 1);
     139         1271 :         if (ret != 0) {
     140            0 :             goto exit;
     141              :         }
     142              : 
     143         1271 :         ret = mbedtls_md_hmac_finish(&ctx, t);
     144         1271 :         if (ret != 0) {
     145            0 :             goto exit;
     146              :         }
     147              : 
     148         1271 :         num_to_copy = i != n ? hash_len : okm_len - where;
     149         1271 :         memcpy(okm + where, t, num_to_copy);
     150         1271 :         where += hash_len;
     151         1271 :         t_len = hash_len;
     152              :     }
     153              : 
     154         1235 : exit:
     155         1235 :     mbedtls_md_free(&ctx);
     156         1235 :     mbedtls_platform_zeroize(t, sizeof(t));
     157              : 
     158         1235 :     return ret;
     159              : }
     160              : 
     161              : #endif /* MBEDTLS_HKDF_C */
        

Generated by: LCOV version 2.0-1