takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /*
kadonotakashi 0:8fdf9a60065b 2 * HKDF implementation -- RFC 5869
kadonotakashi 0:8fdf9a60065b 3 *
kadonotakashi 0:8fdf9a60065b 4 * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
kadonotakashi 0:8fdf9a60065b 5 * SPDX-License-Identifier: Apache-2.0
kadonotakashi 0:8fdf9a60065b 6 *
kadonotakashi 0:8fdf9a60065b 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kadonotakashi 0:8fdf9a60065b 8 * not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 9 * You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 10 *
kadonotakashi 0:8fdf9a60065b 11 * http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 12 *
kadonotakashi 0:8fdf9a60065b 13 * Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kadonotakashi 0:8fdf9a60065b 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 16 * See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 17 * limitations under the License.
kadonotakashi 0:8fdf9a60065b 18 *
kadonotakashi 0:8fdf9a60065b 19 * This file is part of mbed TLS (https://tls.mbed.org)
kadonotakashi 0:8fdf9a60065b 20 */
kadonotakashi 0:8fdf9a60065b 21 #if !defined(MBEDTLS_CONFIG_FILE)
kadonotakashi 0:8fdf9a60065b 22 #include "mbedtls/config.h"
kadonotakashi 0:8fdf9a60065b 23 #else
kadonotakashi 0:8fdf9a60065b 24 #include MBEDTLS_CONFIG_FILE
kadonotakashi 0:8fdf9a60065b 25 #endif
kadonotakashi 0:8fdf9a60065b 26
kadonotakashi 0:8fdf9a60065b 27 #if defined(MBEDTLS_HKDF_C)
kadonotakashi 0:8fdf9a60065b 28
kadonotakashi 0:8fdf9a60065b 29 #include <string.h>
kadonotakashi 0:8fdf9a60065b 30 #include "mbedtls/hkdf.h"
kadonotakashi 0:8fdf9a60065b 31 #include "mbedtls/platform_util.h"
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
kadonotakashi 0:8fdf9a60065b 34 size_t salt_len, const unsigned char *ikm, size_t ikm_len,
kadonotakashi 0:8fdf9a60065b 35 const unsigned char *info, size_t info_len,
kadonotakashi 0:8fdf9a60065b 36 unsigned char *okm, size_t okm_len )
kadonotakashi 0:8fdf9a60065b 37 {
kadonotakashi 0:8fdf9a60065b 38 int ret;
kadonotakashi 0:8fdf9a60065b 39 unsigned char prk[MBEDTLS_MD_MAX_SIZE];
kadonotakashi 0:8fdf9a60065b 40
kadonotakashi 0:8fdf9a60065b 41 ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
kadonotakashi 0:8fdf9a60065b 42
kadonotakashi 0:8fdf9a60065b 43 if( ret == 0 )
kadonotakashi 0:8fdf9a60065b 44 {
kadonotakashi 0:8fdf9a60065b 45 ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ),
kadonotakashi 0:8fdf9a60065b 46 info, info_len, okm, okm_len );
kadonotakashi 0:8fdf9a60065b 47 }
kadonotakashi 0:8fdf9a60065b 48
kadonotakashi 0:8fdf9a60065b 49 mbedtls_platform_zeroize( prk, sizeof( prk ) );
kadonotakashi 0:8fdf9a60065b 50
kadonotakashi 0:8fdf9a60065b 51 return( ret );
kadonotakashi 0:8fdf9a60065b 52 }
kadonotakashi 0:8fdf9a60065b 53
kadonotakashi 0:8fdf9a60065b 54 int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
kadonotakashi 0:8fdf9a60065b 55 const unsigned char *salt, size_t salt_len,
kadonotakashi 0:8fdf9a60065b 56 const unsigned char *ikm, size_t ikm_len,
kadonotakashi 0:8fdf9a60065b 57 unsigned char *prk )
kadonotakashi 0:8fdf9a60065b 58 {
kadonotakashi 0:8fdf9a60065b 59 unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' };
kadonotakashi 0:8fdf9a60065b 60
kadonotakashi 0:8fdf9a60065b 61 if( salt == NULL )
kadonotakashi 0:8fdf9a60065b 62 {
kadonotakashi 0:8fdf9a60065b 63 size_t hash_len;
kadonotakashi 0:8fdf9a60065b 64
kadonotakashi 0:8fdf9a60065b 65 if( salt_len != 0 )
kadonotakashi 0:8fdf9a60065b 66 {
kadonotakashi 0:8fdf9a60065b 67 return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
kadonotakashi 0:8fdf9a60065b 68 }
kadonotakashi 0:8fdf9a60065b 69
kadonotakashi 0:8fdf9a60065b 70 hash_len = mbedtls_md_get_size( md );
kadonotakashi 0:8fdf9a60065b 71
kadonotakashi 0:8fdf9a60065b 72 if( hash_len == 0 )
kadonotakashi 0:8fdf9a60065b 73 {
kadonotakashi 0:8fdf9a60065b 74 return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
kadonotakashi 0:8fdf9a60065b 75 }
kadonotakashi 0:8fdf9a60065b 76
kadonotakashi 0:8fdf9a60065b 77 salt = null_salt;
kadonotakashi 0:8fdf9a60065b 78 salt_len = hash_len;
kadonotakashi 0:8fdf9a60065b 79 }
kadonotakashi 0:8fdf9a60065b 80
kadonotakashi 0:8fdf9a60065b 81 return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) );
kadonotakashi 0:8fdf9a60065b 82 }
kadonotakashi 0:8fdf9a60065b 83
kadonotakashi 0:8fdf9a60065b 84 int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
kadonotakashi 0:8fdf9a60065b 85 size_t prk_len, const unsigned char *info,
kadonotakashi 0:8fdf9a60065b 86 size_t info_len, unsigned char *okm, size_t okm_len )
kadonotakashi 0:8fdf9a60065b 87 {
kadonotakashi 0:8fdf9a60065b 88 size_t hash_len;
kadonotakashi 0:8fdf9a60065b 89 size_t where = 0;
kadonotakashi 0:8fdf9a60065b 90 size_t n;
kadonotakashi 0:8fdf9a60065b 91 size_t t_len = 0;
kadonotakashi 0:8fdf9a60065b 92 size_t i;
kadonotakashi 0:8fdf9a60065b 93 int ret = 0;
kadonotakashi 0:8fdf9a60065b 94 mbedtls_md_context_t ctx;
kadonotakashi 0:8fdf9a60065b 95 unsigned char t[MBEDTLS_MD_MAX_SIZE];
kadonotakashi 0:8fdf9a60065b 96
kadonotakashi 0:8fdf9a60065b 97 if( okm == NULL )
kadonotakashi 0:8fdf9a60065b 98 {
kadonotakashi 0:8fdf9a60065b 99 return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
kadonotakashi 0:8fdf9a60065b 100 }
kadonotakashi 0:8fdf9a60065b 101
kadonotakashi 0:8fdf9a60065b 102 hash_len = mbedtls_md_get_size( md );
kadonotakashi 0:8fdf9a60065b 103
kadonotakashi 0:8fdf9a60065b 104 if( prk_len < hash_len || hash_len == 0 )
kadonotakashi 0:8fdf9a60065b 105 {
kadonotakashi 0:8fdf9a60065b 106 return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
kadonotakashi 0:8fdf9a60065b 107 }
kadonotakashi 0:8fdf9a60065b 108
kadonotakashi 0:8fdf9a60065b 109 if( info == NULL )
kadonotakashi 0:8fdf9a60065b 110 {
kadonotakashi 0:8fdf9a60065b 111 info = (const unsigned char *) "";
kadonotakashi 0:8fdf9a60065b 112 info_len = 0;
kadonotakashi 0:8fdf9a60065b 113 }
kadonotakashi 0:8fdf9a60065b 114
kadonotakashi 0:8fdf9a60065b 115 n = okm_len / hash_len;
kadonotakashi 0:8fdf9a60065b 116
kadonotakashi 0:8fdf9a60065b 117 if( (okm_len % hash_len) != 0 )
kadonotakashi 0:8fdf9a60065b 118 {
kadonotakashi 0:8fdf9a60065b 119 n++;
kadonotakashi 0:8fdf9a60065b 120 }
kadonotakashi 0:8fdf9a60065b 121
kadonotakashi 0:8fdf9a60065b 122 /*
kadonotakashi 0:8fdf9a60065b 123 * Per RFC 5869 Section 2.3, okm_len must not exceed
kadonotakashi 0:8fdf9a60065b 124 * 255 times the hash length
kadonotakashi 0:8fdf9a60065b 125 */
kadonotakashi 0:8fdf9a60065b 126 if( n > 255 )
kadonotakashi 0:8fdf9a60065b 127 {
kadonotakashi 0:8fdf9a60065b 128 return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
kadonotakashi 0:8fdf9a60065b 129 }
kadonotakashi 0:8fdf9a60065b 130
kadonotakashi 0:8fdf9a60065b 131 mbedtls_md_init( &ctx );
kadonotakashi 0:8fdf9a60065b 132
kadonotakashi 0:8fdf9a60065b 133 if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 )
kadonotakashi 0:8fdf9a60065b 134 {
kadonotakashi 0:8fdf9a60065b 135 goto exit;
kadonotakashi 0:8fdf9a60065b 136 }
kadonotakashi 0:8fdf9a60065b 137
kadonotakashi 0:8fdf9a60065b 138 /*
kadonotakashi 0:8fdf9a60065b 139 * Compute T = T(1) | T(2) | T(3) | ... | T(N)
kadonotakashi 0:8fdf9a60065b 140 * Where T(N) is defined in RFC 5869 Section 2.3
kadonotakashi 0:8fdf9a60065b 141 */
kadonotakashi 0:8fdf9a60065b 142 for( i = 1; i <= n; i++ )
kadonotakashi 0:8fdf9a60065b 143 {
kadonotakashi 0:8fdf9a60065b 144 size_t num_to_copy;
kadonotakashi 0:8fdf9a60065b 145 unsigned char c = i & 0xff;
kadonotakashi 0:8fdf9a60065b 146
kadonotakashi 0:8fdf9a60065b 147 ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len );
kadonotakashi 0:8fdf9a60065b 148 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 149 {
kadonotakashi 0:8fdf9a60065b 150 goto exit;
kadonotakashi 0:8fdf9a60065b 151 }
kadonotakashi 0:8fdf9a60065b 152
kadonotakashi 0:8fdf9a60065b 153 ret = mbedtls_md_hmac_update( &ctx, t, t_len );
kadonotakashi 0:8fdf9a60065b 154 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 155 {
kadonotakashi 0:8fdf9a60065b 156 goto exit;
kadonotakashi 0:8fdf9a60065b 157 }
kadonotakashi 0:8fdf9a60065b 158
kadonotakashi 0:8fdf9a60065b 159 ret = mbedtls_md_hmac_update( &ctx, info, info_len );
kadonotakashi 0:8fdf9a60065b 160 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 161 {
kadonotakashi 0:8fdf9a60065b 162 goto exit;
kadonotakashi 0:8fdf9a60065b 163 }
kadonotakashi 0:8fdf9a60065b 164
kadonotakashi 0:8fdf9a60065b 165 /* The constant concatenated to the end of each T(n) is a single octet.
kadonotakashi 0:8fdf9a60065b 166 * */
kadonotakashi 0:8fdf9a60065b 167 ret = mbedtls_md_hmac_update( &ctx, &c, 1 );
kadonotakashi 0:8fdf9a60065b 168 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 169 {
kadonotakashi 0:8fdf9a60065b 170 goto exit;
kadonotakashi 0:8fdf9a60065b 171 }
kadonotakashi 0:8fdf9a60065b 172
kadonotakashi 0:8fdf9a60065b 173 ret = mbedtls_md_hmac_finish( &ctx, t );
kadonotakashi 0:8fdf9a60065b 174 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 175 {
kadonotakashi 0:8fdf9a60065b 176 goto exit;
kadonotakashi 0:8fdf9a60065b 177 }
kadonotakashi 0:8fdf9a60065b 178
kadonotakashi 0:8fdf9a60065b 179 num_to_copy = i != n ? hash_len : okm_len - where;
kadonotakashi 0:8fdf9a60065b 180 memcpy( okm + where, t, num_to_copy );
kadonotakashi 0:8fdf9a60065b 181 where += hash_len;
kadonotakashi 0:8fdf9a60065b 182 t_len = hash_len;
kadonotakashi 0:8fdf9a60065b 183 }
kadonotakashi 0:8fdf9a60065b 184
kadonotakashi 0:8fdf9a60065b 185 exit:
kadonotakashi 0:8fdf9a60065b 186 mbedtls_md_free( &ctx );
kadonotakashi 0:8fdf9a60065b 187 mbedtls_platform_zeroize( t, sizeof( t ) );
kadonotakashi 0:8fdf9a60065b 188
kadonotakashi 0:8fdf9a60065b 189 return( ret );
kadonotakashi 0:8fdf9a60065b 190 }
kadonotakashi 0:8fdf9a60065b 191
kadonotakashi 0:8fdf9a60065b 192 #endif /* MBEDTLS_HKDF_C */