1 /* 2 * Copyright (c) 2014, Linaro Limited 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <crypto/crypto.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <tee/tee_cryp_hkdf.h> 32 #include <tee/tee_cryp_utl.h> 33 #include <utee_defines.h> 34 35 36 static const uint8_t zero_salt[TEE_MAX_HASH_SIZE]; 37 38 static TEE_Result hkdf_extract(uint32_t hash_id, const uint8_t *ikm, 39 size_t ikm_len, const uint8_t *salt, 40 size_t salt_len, uint8_t *prk, size_t *prk_len) 41 { 42 TEE_Result res; 43 size_t ctx_size; 44 void *ctx = NULL; 45 uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id); 46 uint32_t hmac_algo = (TEE_OPERATION_MAC << 28) | hash_id; 47 48 if (!salt || !salt_len) { 49 /* 50 * RFC 5869 section 2.2: 51 * If not provided, [the salt] is set to a string of HashLen 52 * zeros 53 */ 54 salt = zero_salt; 55 res = tee_hash_get_digest_size(hash_algo, &salt_len); 56 if (res != TEE_SUCCESS) 57 goto out; 58 } 59 60 res = crypto_mac_get_ctx_size(hmac_algo, &ctx_size); 61 if (res != TEE_SUCCESS) 62 goto out; 63 64 ctx = malloc(ctx_size); 65 if (!ctx) { 66 res = TEE_ERROR_OUT_OF_MEMORY; 67 goto out; 68 } 69 70 /* 71 * RFC 5869 section 2.1: "Note that in the extract step, 'IKM' is used 72 * as the HMAC input, not as the HMAC key." 73 * Therefore, salt is the HMAC key in the formula from section 2.2: 74 * "PRK = HMAC-Hash(salt, IKM)" 75 */ 76 res = crypto_mac_init(ctx, hmac_algo, salt, salt_len); 77 if (res != TEE_SUCCESS) 78 goto out; 79 80 res = crypto_mac_update(ctx, hmac_algo, ikm, ikm_len); 81 if (res != TEE_SUCCESS) 82 goto out; 83 84 res = crypto_mac_final(ctx, hmac_algo, prk, *prk_len); 85 if (res != TEE_SUCCESS) 86 goto out; 87 88 res = tee_hash_get_digest_size(hash_algo, prk_len); 89 out: 90 free(ctx); 91 return res; 92 } 93 94 static TEE_Result hkdf_expand(uint32_t hash_id, const uint8_t *prk, 95 size_t prk_len, const uint8_t *info, 96 size_t info_len, uint8_t *okm, size_t okm_len) 97 { 98 uint8_t tn[TEE_MAX_HASH_SIZE]; 99 size_t tn_len, hash_len, i, n, where, ctx_size; 100 TEE_Result res = TEE_SUCCESS; 101 void *ctx = NULL; 102 uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id); 103 uint32_t hmac_algo = TEE_ALG_HMAC_ALGO(hash_id); 104 105 res = tee_hash_get_digest_size(hash_algo, &hash_len); 106 if (res != TEE_SUCCESS) 107 goto out; 108 109 if (!okm || prk_len < hash_len) { 110 res = TEE_ERROR_BAD_STATE; 111 goto out; 112 } 113 114 if (!info) 115 info_len = 0; 116 117 res = crypto_mac_get_ctx_size(hmac_algo, &ctx_size); 118 if (res != TEE_SUCCESS) 119 goto out; 120 121 ctx = malloc(ctx_size); 122 if (!ctx) { 123 res = TEE_ERROR_OUT_OF_MEMORY; 124 goto out; 125 } 126 127 /* N = ceil(L/HashLen) */ 128 n = okm_len / hash_len; 129 if ((okm_len % hash_len) != 0) 130 n++; 131 132 if (n > 255) { 133 res = TEE_ERROR_BAD_PARAMETERS; 134 goto out; 135 } 136 137 138 /* 139 * RFC 5869 section 2.3 140 * T = T(1) | T(2) | T(3) | ... | T(N) 141 * OKM = first L octets of T 142 * T(0) = empty string (zero length) 143 * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01) 144 * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02) 145 * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03) 146 * ... 147 */ 148 tn_len = 0; 149 where = 0; 150 for (i = 1; i <= n; i++) { 151 uint8_t c = i; 152 153 res = crypto_mac_init(ctx, hmac_algo, prk, prk_len); 154 if (res != TEE_SUCCESS) 155 goto out; 156 res = crypto_mac_update(ctx, hmac_algo, tn, tn_len); 157 if (res != TEE_SUCCESS) 158 goto out; 159 res = crypto_mac_update(ctx, hmac_algo, info, info_len); 160 if (res != TEE_SUCCESS) 161 goto out; 162 res = crypto_mac_update(ctx, hmac_algo, &c, 1); 163 if (res != TEE_SUCCESS) 164 goto out; 165 res = crypto_mac_final(ctx, hmac_algo, tn, sizeof(tn)); 166 if (res != TEE_SUCCESS) 167 goto out; 168 169 memcpy(okm + where, tn, (i < n) ? hash_len : (okm_len - where)); 170 where += hash_len; 171 tn_len = hash_len; 172 } 173 174 out: 175 free(ctx); 176 return res; 177 } 178 179 TEE_Result tee_cryp_hkdf(uint32_t hash_id, const uint8_t *ikm, size_t ikm_len, 180 const uint8_t *salt, size_t salt_len, 181 const uint8_t *info, size_t info_len, uint8_t *okm, 182 size_t okm_len) 183 { 184 TEE_Result res; 185 uint8_t prk[TEE_MAX_HASH_SIZE]; 186 size_t prk_len = sizeof(prk); 187 188 res = hkdf_extract(hash_id, ikm, ikm_len, salt, salt_len, prk, 189 &prk_len); 190 if (res != TEE_SUCCESS) 191 return res; 192 res = hkdf_expand(hash_id, prk, prk_len, info, info_len, okm, 193 okm_len); 194 195 return res; 196 } 197