Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
hkdf.c
00001 /* 00002 * HKDF implementation -- RFC 5869 00003 * 00004 * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 #if !defined(MBEDTLS_CONFIG_FILE) 00022 #include "mbedtls/config.h" 00023 #else 00024 #include MBEDTLS_CONFIG_FILE 00025 #endif 00026 00027 #if defined(MBEDTLS_HKDF_C) 00028 00029 #include <string.h> 00030 #include "mbedtls/hkdf.h" 00031 #include "mbedtls/platform_util.h" 00032 00033 int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, 00034 size_t salt_len, const unsigned char *ikm, size_t ikm_len, 00035 const unsigned char *info, size_t info_len, 00036 unsigned char *okm, size_t okm_len ) 00037 { 00038 int ret; 00039 unsigned char prk[MBEDTLS_MD_MAX_SIZE]; 00040 00041 ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk ); 00042 00043 if( ret == 0 ) 00044 { 00045 ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ), 00046 info, info_len, okm, okm_len ); 00047 } 00048 00049 mbedtls_platform_zeroize( prk, sizeof( prk ) ); 00050 00051 return( ret ); 00052 } 00053 00054 int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, 00055 const unsigned char *salt, size_t salt_len, 00056 const unsigned char *ikm, size_t ikm_len, 00057 unsigned char *prk ) 00058 { 00059 unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' }; 00060 00061 if( salt == NULL ) 00062 { 00063 size_t hash_len; 00064 00065 if( salt_len != 0 ) 00066 { 00067 return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; 00068 } 00069 00070 hash_len = mbedtls_md_get_size( md ); 00071 00072 if( hash_len == 0 ) 00073 { 00074 return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; 00075 } 00076 00077 salt = null_salt; 00078 salt_len = hash_len; 00079 } 00080 00081 return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) ); 00082 } 00083 00084 int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, 00085 size_t prk_len, const unsigned char *info, 00086 size_t info_len, unsigned char *okm, size_t okm_len ) 00087 { 00088 size_t hash_len; 00089 size_t where = 0; 00090 size_t n; 00091 size_t t_len = 0; 00092 size_t i; 00093 int ret = 0; 00094 mbedtls_md_context_t ctx; 00095 unsigned char t[MBEDTLS_MD_MAX_SIZE]; 00096 00097 if( okm == NULL ) 00098 { 00099 return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); 00100 } 00101 00102 hash_len = mbedtls_md_get_size( md ); 00103 00104 if( prk_len < hash_len || hash_len == 0 ) 00105 { 00106 return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); 00107 } 00108 00109 if( info == NULL ) 00110 { 00111 info = (const unsigned char *) ""; 00112 info_len = 0; 00113 } 00114 00115 n = okm_len / hash_len; 00116 00117 if( (okm_len % hash_len) != 0 ) 00118 { 00119 n++; 00120 } 00121 00122 /* 00123 * Per RFC 5869 Section 2.3, okm_len must not exceed 00124 * 255 times the hash length 00125 */ 00126 if( n > 255 ) 00127 { 00128 return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); 00129 } 00130 00131 mbedtls_md_init( &ctx ); 00132 00133 if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 ) 00134 { 00135 goto exit; 00136 } 00137 00138 /* 00139 * Compute T = T(1) | T(2) | T(3) | ... | T(N) 00140 * Where T(N) is defined in RFC 5869 Section 2.3 00141 */ 00142 for( i = 1; i <= n; i++ ) 00143 { 00144 size_t num_to_copy; 00145 unsigned char c = i & 0xff; 00146 00147 ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len ); 00148 if( ret != 0 ) 00149 { 00150 goto exit; 00151 } 00152 00153 ret = mbedtls_md_hmac_update( &ctx, t, t_len ); 00154 if( ret != 0 ) 00155 { 00156 goto exit; 00157 } 00158 00159 ret = mbedtls_md_hmac_update( &ctx, info, info_len ); 00160 if( ret != 0 ) 00161 { 00162 goto exit; 00163 } 00164 00165 /* The constant concatenated to the end of each T(n) is a single octet. 00166 * */ 00167 ret = mbedtls_md_hmac_update( &ctx, &c, 1 ); 00168 if( ret != 0 ) 00169 { 00170 goto exit; 00171 } 00172 00173 ret = mbedtls_md_hmac_finish( &ctx, t ); 00174 if( ret != 0 ) 00175 { 00176 goto exit; 00177 } 00178 00179 num_to_copy = i != n ? hash_len : okm_len - where; 00180 memcpy( okm + where, t, num_to_copy ); 00181 where += hash_len; 00182 t_len = hash_len; 00183 } 00184 00185 exit: 00186 mbedtls_md_free( &ctx ); 00187 mbedtls_platform_zeroize( t, sizeof( t ) ); 00188 00189 return( ret ); 00190 } 00191 00192 #endif /* MBEDTLS_HKDF_C */
Generated on Tue Jul 12 2022 13:54:24 by
