A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
0:b86d15c6ba29
fix whitespace in sha512.c

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vanger 0:b86d15c6ba29 1 /* hmac.c
Vanger 0:b86d15c6ba29 2 *
Vanger 0:b86d15c6ba29 3 * Copyright (C) 2006-2014 wolfSSL Inc.
Vanger 0:b86d15c6ba29 4 *
Vanger 0:b86d15c6ba29 5 * This file is part of CyaSSL.
Vanger 0:b86d15c6ba29 6 *
Vanger 0:b86d15c6ba29 7 * CyaSSL is free software; you can redistribute it and/or modify
Vanger 0:b86d15c6ba29 8 * it under the terms of the GNU General Public License as published by
Vanger 0:b86d15c6ba29 9 * the Free Software Foundation; either version 2 of the License, or
Vanger 0:b86d15c6ba29 10 * (at your option) any later version.
Vanger 0:b86d15c6ba29 11 *
Vanger 0:b86d15c6ba29 12 * CyaSSL is distributed in the hope that it will be useful,
Vanger 0:b86d15c6ba29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Vanger 0:b86d15c6ba29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Vanger 0:b86d15c6ba29 15 * GNU General Public License for more details.
Vanger 0:b86d15c6ba29 16 *
Vanger 0:b86d15c6ba29 17 * You should have received a copy of the GNU General Public License
Vanger 0:b86d15c6ba29 18 * along with this program; if not, write to the Free Software
Vanger 0:b86d15c6ba29 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Vanger 0:b86d15c6ba29 20 */
Vanger 0:b86d15c6ba29 21
Vanger 0:b86d15c6ba29 22 #ifdef HAVE_CONFIG_H
Vanger 0:b86d15c6ba29 23 #include <config.h>
Vanger 0:b86d15c6ba29 24 #endif
Vanger 0:b86d15c6ba29 25
Vanger 0:b86d15c6ba29 26 #include <cyassl/ctaocrypt/settings.h>
Vanger 0:b86d15c6ba29 27
Vanger 0:b86d15c6ba29 28 #ifndef NO_HMAC
Vanger 0:b86d15c6ba29 29
Vanger 0:b86d15c6ba29 30 #ifdef CYASSL_PIC32MZ_HASH
Vanger 0:b86d15c6ba29 31
Vanger 0:b86d15c6ba29 32 #define InitMd5 InitMd5_sw
Vanger 0:b86d15c6ba29 33 #define Md5Update Md5Update_sw
Vanger 0:b86d15c6ba29 34 #define Md5Final Md5Final_sw
Vanger 0:b86d15c6ba29 35
Vanger 0:b86d15c6ba29 36 #define InitSha InitSha_sw
Vanger 0:b86d15c6ba29 37 #define ShaUpdate ShaUpdate_sw
Vanger 0:b86d15c6ba29 38 #define ShaFinal ShaFinal_sw
Vanger 0:b86d15c6ba29 39
Vanger 0:b86d15c6ba29 40 #define InitSha256 InitSha256_sw
Vanger 0:b86d15c6ba29 41 #define Sha256Update Sha256Update_sw
Vanger 0:b86d15c6ba29 42 #define Sha256Final Sha256Final_sw
Vanger 0:b86d15c6ba29 43
Vanger 0:b86d15c6ba29 44 #endif
Vanger 0:b86d15c6ba29 45
Vanger 0:b86d15c6ba29 46 #ifdef HAVE_FIPS
Vanger 0:b86d15c6ba29 47 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
Vanger 0:b86d15c6ba29 48 #define FIPS_NO_WRAPPERS
Vanger 0:b86d15c6ba29 49 #endif
Vanger 0:b86d15c6ba29 50
Vanger 0:b86d15c6ba29 51 #include <cyassl/ctaocrypt/hmac.h>
Vanger 0:b86d15c6ba29 52 #include <cyassl/ctaocrypt/error-crypt.h>
Vanger 0:b86d15c6ba29 53
Vanger 0:b86d15c6ba29 54
Vanger 0:b86d15c6ba29 55 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 56 static void HmacCaviumFinal(Hmac* hmac, byte* hash);
Vanger 0:b86d15c6ba29 57 static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length);
Vanger 0:b86d15c6ba29 58 static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key,
Vanger 0:b86d15c6ba29 59 word32 length);
Vanger 0:b86d15c6ba29 60 #endif
Vanger 0:b86d15c6ba29 61
Vanger 0:b86d15c6ba29 62 static int InitHmac(Hmac* hmac, int type)
Vanger 0:b86d15c6ba29 63 {
Vanger 0:b86d15c6ba29 64 int ret = 0;
Vanger 0:b86d15c6ba29 65
Vanger 0:b86d15c6ba29 66 hmac->innerHashKeyed = 0;
Vanger 0:b86d15c6ba29 67 hmac->macType = (byte)type;
Vanger 0:b86d15c6ba29 68
Vanger 0:b86d15c6ba29 69 if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384
Vanger 0:b86d15c6ba29 70 || type == SHA512 || type == BLAKE2B_ID))
Vanger 0:b86d15c6ba29 71 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 72
Vanger 0:b86d15c6ba29 73 switch (type) {
Vanger 0:b86d15c6ba29 74 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 75 case MD5:
Vanger 0:b86d15c6ba29 76 InitMd5(&hmac->hash.md5);
Vanger 0:b86d15c6ba29 77 break;
Vanger 0:b86d15c6ba29 78 #endif
Vanger 0:b86d15c6ba29 79
Vanger 0:b86d15c6ba29 80 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 81 case SHA:
Vanger 0:b86d15c6ba29 82 ret = InitSha(&hmac->hash.sha);
Vanger 0:b86d15c6ba29 83 break;
Vanger 0:b86d15c6ba29 84 #endif
Vanger 0:b86d15c6ba29 85
Vanger 0:b86d15c6ba29 86 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 87 case SHA256:
Vanger 0:b86d15c6ba29 88 ret = InitSha256(&hmac->hash.sha256);
Vanger 0:b86d15c6ba29 89 break;
Vanger 0:b86d15c6ba29 90 #endif
Vanger 0:b86d15c6ba29 91
Vanger 0:b86d15c6ba29 92 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 93 case SHA384:
Vanger 0:b86d15c6ba29 94 ret = InitSha384(&hmac->hash.sha384);
Vanger 0:b86d15c6ba29 95 break;
Vanger 0:b86d15c6ba29 96 #endif
Vanger 0:b86d15c6ba29 97
Vanger 0:b86d15c6ba29 98 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 99 case SHA512:
Vanger 0:b86d15c6ba29 100 ret = InitSha512(&hmac->hash.sha512);
Vanger 0:b86d15c6ba29 101 break;
Vanger 0:b86d15c6ba29 102 #endif
Vanger 0:b86d15c6ba29 103
Vanger 0:b86d15c6ba29 104 #ifdef HAVE_BLAKE2
Vanger 0:b86d15c6ba29 105 case BLAKE2B_ID:
Vanger 0:b86d15c6ba29 106 ret = InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256);
Vanger 0:b86d15c6ba29 107 break;
Vanger 0:b86d15c6ba29 108 #endif
Vanger 0:b86d15c6ba29 109
Vanger 0:b86d15c6ba29 110 default:
Vanger 0:b86d15c6ba29 111 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 112 }
Vanger 0:b86d15c6ba29 113
Vanger 0:b86d15c6ba29 114 return ret;
Vanger 0:b86d15c6ba29 115 }
Vanger 0:b86d15c6ba29 116
Vanger 0:b86d15c6ba29 117
Vanger 0:b86d15c6ba29 118 int HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
Vanger 0:b86d15c6ba29 119 {
Vanger 0:b86d15c6ba29 120 byte* ip = (byte*) hmac->ipad;
Vanger 0:b86d15c6ba29 121 byte* op = (byte*) hmac->opad;
Vanger 0:b86d15c6ba29 122 word32 i, hmac_block_size = 0;
Vanger 0:b86d15c6ba29 123 int ret;
Vanger 0:b86d15c6ba29 124
Vanger 0:b86d15c6ba29 125 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 126 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC)
Vanger 0:b86d15c6ba29 127 return HmacCaviumSetKey(hmac, type, key, length);
Vanger 0:b86d15c6ba29 128 #endif
Vanger 0:b86d15c6ba29 129
Vanger 0:b86d15c6ba29 130 ret = InitHmac(hmac, type);
Vanger 0:b86d15c6ba29 131 if (ret != 0)
Vanger 0:b86d15c6ba29 132 return ret;
Vanger 0:b86d15c6ba29 133
Vanger 0:b86d15c6ba29 134 #ifdef HAVE_FIPS
Vanger 0:b86d15c6ba29 135 if (length < HMAC_FIPS_MIN_KEY)
Vanger 0:b86d15c6ba29 136 return HMAC_MIN_KEYLEN_E;
Vanger 0:b86d15c6ba29 137 #endif
Vanger 0:b86d15c6ba29 138
Vanger 0:b86d15c6ba29 139 switch (hmac->macType) {
Vanger 0:b86d15c6ba29 140 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 141 case MD5:
Vanger 0:b86d15c6ba29 142 {
Vanger 0:b86d15c6ba29 143 hmac_block_size = MD5_BLOCK_SIZE;
Vanger 0:b86d15c6ba29 144 if (length <= MD5_BLOCK_SIZE) {
Vanger 0:b86d15c6ba29 145 XMEMCPY(ip, key, length);
Vanger 0:b86d15c6ba29 146 }
Vanger 0:b86d15c6ba29 147 else {
Vanger 0:b86d15c6ba29 148 Md5Update(&hmac->hash.md5, key, length);
Vanger 0:b86d15c6ba29 149 Md5Final(&hmac->hash.md5, ip);
Vanger 0:b86d15c6ba29 150 length = MD5_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 151 }
Vanger 0:b86d15c6ba29 152 }
Vanger 0:b86d15c6ba29 153 break;
Vanger 0:b86d15c6ba29 154 #endif
Vanger 0:b86d15c6ba29 155
Vanger 0:b86d15c6ba29 156 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 157 case SHA:
Vanger 0:b86d15c6ba29 158 {
Vanger 0:b86d15c6ba29 159 hmac_block_size = SHA_BLOCK_SIZE;
Vanger 0:b86d15c6ba29 160 if (length <= SHA_BLOCK_SIZE) {
Vanger 0:b86d15c6ba29 161 XMEMCPY(ip, key, length);
Vanger 0:b86d15c6ba29 162 }
Vanger 0:b86d15c6ba29 163 else {
Vanger 0:b86d15c6ba29 164 ShaUpdate(&hmac->hash.sha, key, length);
Vanger 0:b86d15c6ba29 165 ShaFinal(&hmac->hash.sha, ip);
Vanger 0:b86d15c6ba29 166 length = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 167 }
Vanger 0:b86d15c6ba29 168 }
Vanger 0:b86d15c6ba29 169 break;
Vanger 0:b86d15c6ba29 170 #endif
Vanger 0:b86d15c6ba29 171
Vanger 0:b86d15c6ba29 172 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 173 case SHA256:
Vanger 0:b86d15c6ba29 174 {
Vanger 0:b86d15c6ba29 175 hmac_block_size = SHA256_BLOCK_SIZE;
Vanger 0:b86d15c6ba29 176 if (length <= SHA256_BLOCK_SIZE) {
Vanger 0:b86d15c6ba29 177 XMEMCPY(ip, key, length);
Vanger 0:b86d15c6ba29 178 }
Vanger 0:b86d15c6ba29 179 else {
Vanger 0:b86d15c6ba29 180 ret = Sha256Update(&hmac->hash.sha256, key, length);
Vanger 0:b86d15c6ba29 181 if (ret != 0)
Vanger 0:b86d15c6ba29 182 return ret;
Vanger 0:b86d15c6ba29 183
Vanger 0:b86d15c6ba29 184 ret = Sha256Final(&hmac->hash.sha256, ip);
Vanger 0:b86d15c6ba29 185 if (ret != 0)
Vanger 0:b86d15c6ba29 186 return ret;
Vanger 0:b86d15c6ba29 187
Vanger 0:b86d15c6ba29 188 length = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 189 }
Vanger 0:b86d15c6ba29 190 }
Vanger 0:b86d15c6ba29 191 break;
Vanger 0:b86d15c6ba29 192 #endif
Vanger 0:b86d15c6ba29 193
Vanger 0:b86d15c6ba29 194 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 195 case SHA384:
Vanger 0:b86d15c6ba29 196 {
Vanger 0:b86d15c6ba29 197 hmac_block_size = SHA384_BLOCK_SIZE;
Vanger 0:b86d15c6ba29 198 if (length <= SHA384_BLOCK_SIZE) {
Vanger 0:b86d15c6ba29 199 XMEMCPY(ip, key, length);
Vanger 0:b86d15c6ba29 200 }
Vanger 0:b86d15c6ba29 201 else {
Vanger 0:b86d15c6ba29 202 ret = Sha384Update(&hmac->hash.sha384, key, length);
Vanger 0:b86d15c6ba29 203 if (ret != 0)
Vanger 0:b86d15c6ba29 204 return ret;
Vanger 0:b86d15c6ba29 205
Vanger 0:b86d15c6ba29 206 ret = Sha384Final(&hmac->hash.sha384, ip);
Vanger 0:b86d15c6ba29 207 if (ret != 0)
Vanger 0:b86d15c6ba29 208 return ret;
Vanger 0:b86d15c6ba29 209
Vanger 0:b86d15c6ba29 210 length = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 211 }
Vanger 0:b86d15c6ba29 212 }
Vanger 0:b86d15c6ba29 213 break;
Vanger 0:b86d15c6ba29 214 #endif
Vanger 0:b86d15c6ba29 215
Vanger 0:b86d15c6ba29 216 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 217 case SHA512:
Vanger 0:b86d15c6ba29 218 {
Vanger 0:b86d15c6ba29 219 hmac_block_size = SHA512_BLOCK_SIZE;
Vanger 0:b86d15c6ba29 220 if (length <= SHA512_BLOCK_SIZE) {
Vanger 0:b86d15c6ba29 221 XMEMCPY(ip, key, length);
Vanger 0:b86d15c6ba29 222 }
Vanger 0:b86d15c6ba29 223 else {
Vanger 0:b86d15c6ba29 224 ret = Sha512Update(&hmac->hash.sha512, key, length);
Vanger 0:b86d15c6ba29 225 if (ret != 0)
Vanger 0:b86d15c6ba29 226 return ret;
Vanger 0:b86d15c6ba29 227
Vanger 0:b86d15c6ba29 228 ret = Sha512Final(&hmac->hash.sha512, ip);
Vanger 0:b86d15c6ba29 229 if (ret != 0)
Vanger 0:b86d15c6ba29 230 return ret;
Vanger 0:b86d15c6ba29 231
Vanger 0:b86d15c6ba29 232 length = SHA512_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 233 }
Vanger 0:b86d15c6ba29 234 }
Vanger 0:b86d15c6ba29 235 break;
Vanger 0:b86d15c6ba29 236 #endif
Vanger 0:b86d15c6ba29 237
Vanger 0:b86d15c6ba29 238 #ifdef HAVE_BLAKE2
Vanger 0:b86d15c6ba29 239 case BLAKE2B_ID:
Vanger 0:b86d15c6ba29 240 {
Vanger 0:b86d15c6ba29 241 hmac_block_size = BLAKE2B_BLOCKBYTES;
Vanger 0:b86d15c6ba29 242 if (length <= BLAKE2B_BLOCKBYTES) {
Vanger 0:b86d15c6ba29 243 XMEMCPY(ip, key, length);
Vanger 0:b86d15c6ba29 244 }
Vanger 0:b86d15c6ba29 245 else {
Vanger 0:b86d15c6ba29 246 ret = Blake2bUpdate(&hmac->hash.blake2b, key, length);
Vanger 0:b86d15c6ba29 247 if (ret != 0)
Vanger 0:b86d15c6ba29 248 return ret;
Vanger 0:b86d15c6ba29 249
Vanger 0:b86d15c6ba29 250 ret = Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256);
Vanger 0:b86d15c6ba29 251 if (ret != 0)
Vanger 0:b86d15c6ba29 252 return ret;
Vanger 0:b86d15c6ba29 253
Vanger 0:b86d15c6ba29 254 length = BLAKE2B_256;
Vanger 0:b86d15c6ba29 255 }
Vanger 0:b86d15c6ba29 256 }
Vanger 0:b86d15c6ba29 257 break;
Vanger 0:b86d15c6ba29 258 #endif
Vanger 0:b86d15c6ba29 259
Vanger 0:b86d15c6ba29 260 default:
Vanger 0:b86d15c6ba29 261 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 262 }
Vanger 0:b86d15c6ba29 263 if (length < hmac_block_size)
Vanger 0:b86d15c6ba29 264 XMEMSET(ip + length, 0, hmac_block_size - length);
Vanger 0:b86d15c6ba29 265
Vanger 0:b86d15c6ba29 266 for(i = 0; i < hmac_block_size; i++) {
Vanger 0:b86d15c6ba29 267 op[i] = ip[i] ^ OPAD;
Vanger 0:b86d15c6ba29 268 ip[i] ^= IPAD;
Vanger 0:b86d15c6ba29 269 }
Vanger 0:b86d15c6ba29 270 return 0;
Vanger 0:b86d15c6ba29 271 }
Vanger 0:b86d15c6ba29 272
Vanger 0:b86d15c6ba29 273
Vanger 0:b86d15c6ba29 274 static int HmacKeyInnerHash(Hmac* hmac)
Vanger 0:b86d15c6ba29 275 {
Vanger 0:b86d15c6ba29 276 int ret = 0;
Vanger 0:b86d15c6ba29 277
Vanger 0:b86d15c6ba29 278 switch (hmac->macType) {
Vanger 0:b86d15c6ba29 279 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 280 case MD5:
Vanger 0:b86d15c6ba29 281 Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 282 break;
Vanger 0:b86d15c6ba29 283 #endif
Vanger 0:b86d15c6ba29 284
Vanger 0:b86d15c6ba29 285 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 286 case SHA:
Vanger 0:b86d15c6ba29 287 ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 288 break;
Vanger 0:b86d15c6ba29 289 #endif
Vanger 0:b86d15c6ba29 290
Vanger 0:b86d15c6ba29 291 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 292 case SHA256:
Vanger 0:b86d15c6ba29 293 ret = Sha256Update(&hmac->hash.sha256,
Vanger 0:b86d15c6ba29 294 (byte*) hmac->ipad, SHA256_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 295 if (ret != 0)
Vanger 0:b86d15c6ba29 296 return ret;
Vanger 0:b86d15c6ba29 297 break;
Vanger 0:b86d15c6ba29 298 #endif
Vanger 0:b86d15c6ba29 299
Vanger 0:b86d15c6ba29 300 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 301 case SHA384:
Vanger 0:b86d15c6ba29 302 ret = Sha384Update(&hmac->hash.sha384,
Vanger 0:b86d15c6ba29 303 (byte*) hmac->ipad, SHA384_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 304 if (ret != 0)
Vanger 0:b86d15c6ba29 305 return ret;
Vanger 0:b86d15c6ba29 306 break;
Vanger 0:b86d15c6ba29 307 #endif
Vanger 0:b86d15c6ba29 308
Vanger 0:b86d15c6ba29 309 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 310 case SHA512:
Vanger 0:b86d15c6ba29 311 ret = Sha512Update(&hmac->hash.sha512,
Vanger 0:b86d15c6ba29 312 (byte*) hmac->ipad, SHA512_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 313 if (ret != 0)
Vanger 0:b86d15c6ba29 314 return ret;
Vanger 0:b86d15c6ba29 315 break;
Vanger 0:b86d15c6ba29 316 #endif
Vanger 0:b86d15c6ba29 317
Vanger 0:b86d15c6ba29 318 #ifdef HAVE_BLAKE2
Vanger 0:b86d15c6ba29 319 case BLAKE2B_ID:
Vanger 0:b86d15c6ba29 320 ret = Blake2bUpdate(&hmac->hash.blake2b,
Vanger 0:b86d15c6ba29 321 (byte*) hmac->ipad,BLAKE2B_BLOCKBYTES);
Vanger 0:b86d15c6ba29 322 if (ret != 0)
Vanger 0:b86d15c6ba29 323 return ret;
Vanger 0:b86d15c6ba29 324 break;
Vanger 0:b86d15c6ba29 325 #endif
Vanger 0:b86d15c6ba29 326
Vanger 0:b86d15c6ba29 327 default:
Vanger 0:b86d15c6ba29 328 break;
Vanger 0:b86d15c6ba29 329 }
Vanger 0:b86d15c6ba29 330
Vanger 0:b86d15c6ba29 331 hmac->innerHashKeyed = 1;
Vanger 0:b86d15c6ba29 332
Vanger 0:b86d15c6ba29 333 return ret;
Vanger 0:b86d15c6ba29 334 }
Vanger 0:b86d15c6ba29 335
Vanger 0:b86d15c6ba29 336
Vanger 0:b86d15c6ba29 337 int HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
Vanger 0:b86d15c6ba29 338 {
Vanger 0:b86d15c6ba29 339 int ret;
Vanger 0:b86d15c6ba29 340
Vanger 0:b86d15c6ba29 341 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 342 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC)
Vanger 0:b86d15c6ba29 343 return HmacCaviumUpdate(hmac, msg, length);
Vanger 0:b86d15c6ba29 344 #endif
Vanger 0:b86d15c6ba29 345
Vanger 0:b86d15c6ba29 346 if (!hmac->innerHashKeyed) {
Vanger 0:b86d15c6ba29 347 ret = HmacKeyInnerHash(hmac);
Vanger 0:b86d15c6ba29 348 if (ret != 0)
Vanger 0:b86d15c6ba29 349 return ret;
Vanger 0:b86d15c6ba29 350 }
Vanger 0:b86d15c6ba29 351
Vanger 0:b86d15c6ba29 352 switch (hmac->macType) {
Vanger 0:b86d15c6ba29 353 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 354 case MD5:
Vanger 0:b86d15c6ba29 355 Md5Update(&hmac->hash.md5, msg, length);
Vanger 0:b86d15c6ba29 356 break;
Vanger 0:b86d15c6ba29 357 #endif
Vanger 0:b86d15c6ba29 358
Vanger 0:b86d15c6ba29 359 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 360 case SHA:
Vanger 0:b86d15c6ba29 361 ShaUpdate(&hmac->hash.sha, msg, length);
Vanger 0:b86d15c6ba29 362 break;
Vanger 0:b86d15c6ba29 363 #endif
Vanger 0:b86d15c6ba29 364
Vanger 0:b86d15c6ba29 365 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 366 case SHA256:
Vanger 0:b86d15c6ba29 367 ret = Sha256Update(&hmac->hash.sha256, msg, length);
Vanger 0:b86d15c6ba29 368 if (ret != 0)
Vanger 0:b86d15c6ba29 369 return ret;
Vanger 0:b86d15c6ba29 370 break;
Vanger 0:b86d15c6ba29 371 #endif
Vanger 0:b86d15c6ba29 372
Vanger 0:b86d15c6ba29 373 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 374 case SHA384:
Vanger 0:b86d15c6ba29 375 ret = Sha384Update(&hmac->hash.sha384, msg, length);
Vanger 0:b86d15c6ba29 376 if (ret != 0)
Vanger 0:b86d15c6ba29 377 return ret;
Vanger 0:b86d15c6ba29 378 break;
Vanger 0:b86d15c6ba29 379 #endif
Vanger 0:b86d15c6ba29 380
Vanger 0:b86d15c6ba29 381 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 382 case SHA512:
Vanger 0:b86d15c6ba29 383 ret = Sha512Update(&hmac->hash.sha512, msg, length);
Vanger 0:b86d15c6ba29 384 if (ret != 0)
Vanger 0:b86d15c6ba29 385 return ret;
Vanger 0:b86d15c6ba29 386 break;
Vanger 0:b86d15c6ba29 387 #endif
Vanger 0:b86d15c6ba29 388
Vanger 0:b86d15c6ba29 389 #ifdef HAVE_BLAKE2
Vanger 0:b86d15c6ba29 390 case BLAKE2B_ID:
Vanger 0:b86d15c6ba29 391 ret = Blake2bUpdate(&hmac->hash.blake2b, msg, length);
Vanger 0:b86d15c6ba29 392 if (ret != 0)
Vanger 0:b86d15c6ba29 393 return ret;
Vanger 0:b86d15c6ba29 394 break;
Vanger 0:b86d15c6ba29 395 #endif
Vanger 0:b86d15c6ba29 396
Vanger 0:b86d15c6ba29 397 default:
Vanger 0:b86d15c6ba29 398 break;
Vanger 0:b86d15c6ba29 399 }
Vanger 0:b86d15c6ba29 400
Vanger 0:b86d15c6ba29 401 return 0;
Vanger 0:b86d15c6ba29 402 }
Vanger 0:b86d15c6ba29 403
Vanger 0:b86d15c6ba29 404
Vanger 0:b86d15c6ba29 405 int HmacFinal(Hmac* hmac, byte* hash)
Vanger 0:b86d15c6ba29 406 {
Vanger 0:b86d15c6ba29 407 int ret;
Vanger 0:b86d15c6ba29 408
Vanger 0:b86d15c6ba29 409 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 410 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC)
Vanger 0:b86d15c6ba29 411 return HmacCaviumFinal(hmac, hash);
Vanger 0:b86d15c6ba29 412 #endif
Vanger 0:b86d15c6ba29 413
Vanger 0:b86d15c6ba29 414 if (!hmac->innerHashKeyed) {
Vanger 0:b86d15c6ba29 415 ret = HmacKeyInnerHash(hmac);
Vanger 0:b86d15c6ba29 416 if (ret != 0)
Vanger 0:b86d15c6ba29 417 return ret;
Vanger 0:b86d15c6ba29 418 }
Vanger 0:b86d15c6ba29 419
Vanger 0:b86d15c6ba29 420 switch (hmac->macType) {
Vanger 0:b86d15c6ba29 421 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 422 case MD5:
Vanger 0:b86d15c6ba29 423 {
Vanger 0:b86d15c6ba29 424 Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash);
Vanger 0:b86d15c6ba29 425
Vanger 0:b86d15c6ba29 426 Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 427 Md5Update(&hmac->hash.md5,
Vanger 0:b86d15c6ba29 428 (byte*) hmac->innerHash, MD5_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 429
Vanger 0:b86d15c6ba29 430 Md5Final(&hmac->hash.md5, hash);
Vanger 0:b86d15c6ba29 431 }
Vanger 0:b86d15c6ba29 432 break;
Vanger 0:b86d15c6ba29 433 #endif
Vanger 0:b86d15c6ba29 434
Vanger 0:b86d15c6ba29 435 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 436 case SHA:
Vanger 0:b86d15c6ba29 437 {
Vanger 0:b86d15c6ba29 438 ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash);
Vanger 0:b86d15c6ba29 439
Vanger 0:b86d15c6ba29 440 ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 441 ShaUpdate(&hmac->hash.sha,
Vanger 0:b86d15c6ba29 442 (byte*) hmac->innerHash, SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 443
Vanger 0:b86d15c6ba29 444 ShaFinal(&hmac->hash.sha, hash);
Vanger 0:b86d15c6ba29 445 }
Vanger 0:b86d15c6ba29 446 break;
Vanger 0:b86d15c6ba29 447 #endif
Vanger 0:b86d15c6ba29 448
Vanger 0:b86d15c6ba29 449 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 450 case SHA256:
Vanger 0:b86d15c6ba29 451 {
Vanger 0:b86d15c6ba29 452 ret = Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash);
Vanger 0:b86d15c6ba29 453 if (ret != 0)
Vanger 0:b86d15c6ba29 454 return ret;
Vanger 0:b86d15c6ba29 455
Vanger 0:b86d15c6ba29 456 ret = Sha256Update(&hmac->hash.sha256,
Vanger 0:b86d15c6ba29 457 (byte*) hmac->opad, SHA256_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 458 if (ret != 0)
Vanger 0:b86d15c6ba29 459 return ret;
Vanger 0:b86d15c6ba29 460
Vanger 0:b86d15c6ba29 461 ret = Sha256Update(&hmac->hash.sha256,
Vanger 0:b86d15c6ba29 462 (byte*) hmac->innerHash, SHA256_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 463 if (ret != 0)
Vanger 0:b86d15c6ba29 464 return ret;
Vanger 0:b86d15c6ba29 465
Vanger 0:b86d15c6ba29 466 ret = Sha256Final(&hmac->hash.sha256, hash);
Vanger 0:b86d15c6ba29 467 if (ret != 0)
Vanger 0:b86d15c6ba29 468 return ret;
Vanger 0:b86d15c6ba29 469 }
Vanger 0:b86d15c6ba29 470 break;
Vanger 0:b86d15c6ba29 471 #endif
Vanger 0:b86d15c6ba29 472
Vanger 0:b86d15c6ba29 473 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 474 case SHA384:
Vanger 0:b86d15c6ba29 475 {
Vanger 0:b86d15c6ba29 476 ret = Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash);
Vanger 0:b86d15c6ba29 477 if (ret != 0)
Vanger 0:b86d15c6ba29 478 return ret;
Vanger 0:b86d15c6ba29 479
Vanger 0:b86d15c6ba29 480 ret = Sha384Update(&hmac->hash.sha384,
Vanger 0:b86d15c6ba29 481 (byte*) hmac->opad, SHA384_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 482 if (ret != 0)
Vanger 0:b86d15c6ba29 483 return ret;
Vanger 0:b86d15c6ba29 484
Vanger 0:b86d15c6ba29 485 ret = Sha384Update(&hmac->hash.sha384,
Vanger 0:b86d15c6ba29 486 (byte*) hmac->innerHash, SHA384_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 487 if (ret != 0)
Vanger 0:b86d15c6ba29 488 return ret;
Vanger 0:b86d15c6ba29 489
Vanger 0:b86d15c6ba29 490 ret = Sha384Final(&hmac->hash.sha384, hash);
Vanger 0:b86d15c6ba29 491 if (ret != 0)
Vanger 0:b86d15c6ba29 492 return ret;
Vanger 0:b86d15c6ba29 493 }
Vanger 0:b86d15c6ba29 494 break;
Vanger 0:b86d15c6ba29 495 #endif
Vanger 0:b86d15c6ba29 496
Vanger 0:b86d15c6ba29 497 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 498 case SHA512:
Vanger 0:b86d15c6ba29 499 {
Vanger 0:b86d15c6ba29 500 ret = Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash);
Vanger 0:b86d15c6ba29 501 if (ret != 0)
Vanger 0:b86d15c6ba29 502 return ret;
Vanger 0:b86d15c6ba29 503
Vanger 0:b86d15c6ba29 504 ret = Sha512Update(&hmac->hash.sha512,
Vanger 0:b86d15c6ba29 505 (byte*) hmac->opad, SHA512_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 506 if (ret != 0)
Vanger 0:b86d15c6ba29 507 return ret;
Vanger 0:b86d15c6ba29 508
Vanger 0:b86d15c6ba29 509 ret = Sha512Update(&hmac->hash.sha512,
Vanger 0:b86d15c6ba29 510 (byte*) hmac->innerHash, SHA512_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 511 if (ret != 0)
Vanger 0:b86d15c6ba29 512 return ret;
Vanger 0:b86d15c6ba29 513
Vanger 0:b86d15c6ba29 514 ret = Sha512Final(&hmac->hash.sha512, hash);
Vanger 0:b86d15c6ba29 515 if (ret != 0)
Vanger 0:b86d15c6ba29 516 return ret;
Vanger 0:b86d15c6ba29 517 }
Vanger 0:b86d15c6ba29 518 break;
Vanger 0:b86d15c6ba29 519 #endif
Vanger 0:b86d15c6ba29 520
Vanger 0:b86d15c6ba29 521 #ifdef HAVE_BLAKE2
Vanger 0:b86d15c6ba29 522 case BLAKE2B_ID:
Vanger 0:b86d15c6ba29 523 {
Vanger 0:b86d15c6ba29 524 ret = Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash,
Vanger 0:b86d15c6ba29 525 BLAKE2B_256);
Vanger 0:b86d15c6ba29 526 if (ret != 0)
Vanger 0:b86d15c6ba29 527 return ret;
Vanger 0:b86d15c6ba29 528
Vanger 0:b86d15c6ba29 529 ret = Blake2bUpdate(&hmac->hash.blake2b,
Vanger 0:b86d15c6ba29 530 (byte*) hmac->opad, BLAKE2B_BLOCKBYTES);
Vanger 0:b86d15c6ba29 531 if (ret != 0)
Vanger 0:b86d15c6ba29 532 return ret;
Vanger 0:b86d15c6ba29 533
Vanger 0:b86d15c6ba29 534 ret = Blake2bUpdate(&hmac->hash.blake2b,
Vanger 0:b86d15c6ba29 535 (byte*) hmac->innerHash, BLAKE2B_256);
Vanger 0:b86d15c6ba29 536 if (ret != 0)
Vanger 0:b86d15c6ba29 537 return ret;
Vanger 0:b86d15c6ba29 538
Vanger 0:b86d15c6ba29 539 ret = Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256);
Vanger 0:b86d15c6ba29 540 if (ret != 0)
Vanger 0:b86d15c6ba29 541 return ret;
Vanger 0:b86d15c6ba29 542 }
Vanger 0:b86d15c6ba29 543 break;
Vanger 0:b86d15c6ba29 544 #endif
Vanger 0:b86d15c6ba29 545
Vanger 0:b86d15c6ba29 546 default:
Vanger 0:b86d15c6ba29 547 break;
Vanger 0:b86d15c6ba29 548 }
Vanger 0:b86d15c6ba29 549
Vanger 0:b86d15c6ba29 550 hmac->innerHashKeyed = 0;
Vanger 0:b86d15c6ba29 551
Vanger 0:b86d15c6ba29 552 return 0;
Vanger 0:b86d15c6ba29 553 }
Vanger 0:b86d15c6ba29 554
Vanger 0:b86d15c6ba29 555
Vanger 0:b86d15c6ba29 556 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 557
Vanger 0:b86d15c6ba29 558 /* Initiliaze Hmac for use with Nitrox device */
Vanger 0:b86d15c6ba29 559 int HmacInitCavium(Hmac* hmac, int devId)
Vanger 0:b86d15c6ba29 560 {
Vanger 0:b86d15c6ba29 561 if (hmac == NULL)
Vanger 0:b86d15c6ba29 562 return -1;
Vanger 0:b86d15c6ba29 563
Vanger 0:b86d15c6ba29 564 if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0)
Vanger 0:b86d15c6ba29 565 return -1;
Vanger 0:b86d15c6ba29 566
Vanger 0:b86d15c6ba29 567 hmac->keyLen = 0;
Vanger 0:b86d15c6ba29 568 hmac->dataLen = 0;
Vanger 0:b86d15c6ba29 569 hmac->type = 0;
Vanger 0:b86d15c6ba29 570 hmac->devId = devId;
Vanger 0:b86d15c6ba29 571 hmac->magic = CYASSL_HMAC_CAVIUM_MAGIC;
Vanger 0:b86d15c6ba29 572 hmac->data = NULL; /* buffered input data */
Vanger 0:b86d15c6ba29 573
Vanger 0:b86d15c6ba29 574 hmac->innerHashKeyed = 0;
Vanger 0:b86d15c6ba29 575
Vanger 0:b86d15c6ba29 576 return 0;
Vanger 0:b86d15c6ba29 577 }
Vanger 0:b86d15c6ba29 578
Vanger 0:b86d15c6ba29 579
Vanger 0:b86d15c6ba29 580 /* Free Hmac from use with Nitrox device */
Vanger 0:b86d15c6ba29 581 void HmacFreeCavium(Hmac* hmac)
Vanger 0:b86d15c6ba29 582 {
Vanger 0:b86d15c6ba29 583 if (hmac == NULL)
Vanger 0:b86d15c6ba29 584 return;
Vanger 0:b86d15c6ba29 585
Vanger 0:b86d15c6ba29 586 CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId);
Vanger 0:b86d15c6ba29 587 hmac->magic = 0;
Vanger 0:b86d15c6ba29 588 XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP);
Vanger 0:b86d15c6ba29 589 hmac->data = NULL;
Vanger 0:b86d15c6ba29 590 }
Vanger 0:b86d15c6ba29 591
Vanger 0:b86d15c6ba29 592
Vanger 0:b86d15c6ba29 593 static void HmacCaviumFinal(Hmac* hmac, byte* hash)
Vanger 0:b86d15c6ba29 594 {
Vanger 0:b86d15c6ba29 595 word32 requestId;
Vanger 0:b86d15c6ba29 596
Vanger 0:b86d15c6ba29 597 if (CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen,
Vanger 0:b86d15c6ba29 598 (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId,
Vanger 0:b86d15c6ba29 599 hmac->devId) != 0) {
Vanger 0:b86d15c6ba29 600 CYASSL_MSG("Cavium Hmac failed");
Vanger 0:b86d15c6ba29 601 }
Vanger 0:b86d15c6ba29 602 hmac->innerHashKeyed = 0; /* tell update to start over if used again */
Vanger 0:b86d15c6ba29 603 }
Vanger 0:b86d15c6ba29 604
Vanger 0:b86d15c6ba29 605
Vanger 0:b86d15c6ba29 606 static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length)
Vanger 0:b86d15c6ba29 607 {
Vanger 0:b86d15c6ba29 608 word16 add = (word16)length;
Vanger 0:b86d15c6ba29 609 word32 total;
Vanger 0:b86d15c6ba29 610 byte* tmp;
Vanger 0:b86d15c6ba29 611
Vanger 0:b86d15c6ba29 612 if (length > CYASSL_MAX_16BIT) {
Vanger 0:b86d15c6ba29 613 CYASSL_MSG("Too big msg for cavium hmac");
Vanger 0:b86d15c6ba29 614 return;
Vanger 0:b86d15c6ba29 615 }
Vanger 0:b86d15c6ba29 616
Vanger 0:b86d15c6ba29 617 if (hmac->innerHashKeyed == 0) { /* starting new */
Vanger 0:b86d15c6ba29 618 hmac->dataLen = 0;
Vanger 0:b86d15c6ba29 619 hmac->innerHashKeyed = 1;
Vanger 0:b86d15c6ba29 620 }
Vanger 0:b86d15c6ba29 621
Vanger 0:b86d15c6ba29 622 total = add + hmac->dataLen;
Vanger 0:b86d15c6ba29 623 if (total > CYASSL_MAX_16BIT) {
Vanger 0:b86d15c6ba29 624 CYASSL_MSG("Too big msg for cavium hmac");
Vanger 0:b86d15c6ba29 625 return;
Vanger 0:b86d15c6ba29 626 }
Vanger 0:b86d15c6ba29 627
Vanger 0:b86d15c6ba29 628 tmp = XMALLOC(hmac->dataLen + add, NULL,DYNAMIC_TYPE_CAVIUM_TMP);
Vanger 0:b86d15c6ba29 629 if (tmp == NULL) {
Vanger 0:b86d15c6ba29 630 CYASSL_MSG("Out of memory for cavium update");
Vanger 0:b86d15c6ba29 631 return;
Vanger 0:b86d15c6ba29 632 }
Vanger 0:b86d15c6ba29 633 if (hmac->dataLen)
Vanger 0:b86d15c6ba29 634 XMEMCPY(tmp, hmac->data, hmac->dataLen);
Vanger 0:b86d15c6ba29 635 XMEMCPY(tmp + hmac->dataLen, msg, add);
Vanger 0:b86d15c6ba29 636
Vanger 0:b86d15c6ba29 637 hmac->dataLen += add;
Vanger 0:b86d15c6ba29 638 XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP);
Vanger 0:b86d15c6ba29 639 hmac->data = tmp;
Vanger 0:b86d15c6ba29 640 }
Vanger 0:b86d15c6ba29 641
Vanger 0:b86d15c6ba29 642
Vanger 0:b86d15c6ba29 643 static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key,
Vanger 0:b86d15c6ba29 644 word32 length)
Vanger 0:b86d15c6ba29 645 {
Vanger 0:b86d15c6ba29 646 hmac->macType = (byte)type;
Vanger 0:b86d15c6ba29 647 if (type == MD5)
Vanger 0:b86d15c6ba29 648 hmac->type = MD5_TYPE;
Vanger 0:b86d15c6ba29 649 else if (type == SHA)
Vanger 0:b86d15c6ba29 650 hmac->type = SHA1_TYPE;
Vanger 0:b86d15c6ba29 651 else if (type == SHA256)
Vanger 0:b86d15c6ba29 652 hmac->type = SHA256_TYPE;
Vanger 0:b86d15c6ba29 653 else {
Vanger 0:b86d15c6ba29 654 CYASSL_MSG("unsupported cavium hmac type");
Vanger 0:b86d15c6ba29 655 }
Vanger 0:b86d15c6ba29 656
Vanger 0:b86d15c6ba29 657 hmac->innerHashKeyed = 0; /* should we key Startup flag */
Vanger 0:b86d15c6ba29 658
Vanger 0:b86d15c6ba29 659 hmac->keyLen = (word16)length;
Vanger 0:b86d15c6ba29 660 /* store key in ipad */
Vanger 0:b86d15c6ba29 661 XMEMCPY(hmac->ipad, key, length);
Vanger 0:b86d15c6ba29 662 }
Vanger 0:b86d15c6ba29 663
Vanger 0:b86d15c6ba29 664 #endif /* HAVE_CAVIUM */
Vanger 0:b86d15c6ba29 665
Vanger 0:b86d15c6ba29 666 int CyaSSL_GetHmacMaxSize(void)
Vanger 0:b86d15c6ba29 667 {
Vanger 0:b86d15c6ba29 668 return MAX_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 669 }
Vanger 0:b86d15c6ba29 670
Vanger 0:b86d15c6ba29 671 #ifdef HAVE_HKDF
Vanger 0:b86d15c6ba29 672
Vanger 0:b86d15c6ba29 673 #ifndef min
Vanger 0:b86d15c6ba29 674
Vanger 0:b86d15c6ba29 675 static INLINE word32 min(word32 a, word32 b)
Vanger 0:b86d15c6ba29 676 {
Vanger 0:b86d15c6ba29 677 return a > b ? b : a;
Vanger 0:b86d15c6ba29 678 }
Vanger 0:b86d15c6ba29 679
Vanger 0:b86d15c6ba29 680 #endif /* min */
Vanger 0:b86d15c6ba29 681
Vanger 0:b86d15c6ba29 682
Vanger 0:b86d15c6ba29 683 static INLINE int GetHashSizeByType(int type)
Vanger 0:b86d15c6ba29 684 {
Vanger 0:b86d15c6ba29 685 if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384
Vanger 0:b86d15c6ba29 686 || type == SHA512 || type == BLAKE2B_ID))
Vanger 0:b86d15c6ba29 687 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 688
Vanger 0:b86d15c6ba29 689 switch (type) {
Vanger 0:b86d15c6ba29 690 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 691 case MD5:
Vanger 0:b86d15c6ba29 692 return MD5_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 693 break;
Vanger 0:b86d15c6ba29 694 #endif
Vanger 0:b86d15c6ba29 695
Vanger 0:b86d15c6ba29 696 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 697 case SHA:
Vanger 0:b86d15c6ba29 698 return SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 699 break;
Vanger 0:b86d15c6ba29 700 #endif
Vanger 0:b86d15c6ba29 701
Vanger 0:b86d15c6ba29 702 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 703 case SHA256:
Vanger 0:b86d15c6ba29 704 return SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 705 break;
Vanger 0:b86d15c6ba29 706 #endif
Vanger 0:b86d15c6ba29 707
Vanger 0:b86d15c6ba29 708 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 709 case SHA384:
Vanger 0:b86d15c6ba29 710 return SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 711 break;
Vanger 0:b86d15c6ba29 712 #endif
Vanger 0:b86d15c6ba29 713
Vanger 0:b86d15c6ba29 714 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 715 case SHA512:
Vanger 0:b86d15c6ba29 716 return SHA512_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 717 break;
Vanger 0:b86d15c6ba29 718 #endif
Vanger 0:b86d15c6ba29 719
Vanger 0:b86d15c6ba29 720 #ifdef HAVE_BLAKE2
Vanger 0:b86d15c6ba29 721 case BLAKE2B_ID:
Vanger 0:b86d15c6ba29 722 return BLAKE2B_OUTBYTES;
Vanger 0:b86d15c6ba29 723 break;
Vanger 0:b86d15c6ba29 724 #endif
Vanger 0:b86d15c6ba29 725
Vanger 0:b86d15c6ba29 726 default:
Vanger 0:b86d15c6ba29 727 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 728 break;
Vanger 0:b86d15c6ba29 729 }
Vanger 0:b86d15c6ba29 730 }
Vanger 0:b86d15c6ba29 731
Vanger 0:b86d15c6ba29 732
Vanger 0:b86d15c6ba29 733 /* HMAC-KDF with hash type, optional salt and info, return 0 on success */
Vanger 0:b86d15c6ba29 734 int HKDF(int type, const byte* inKey, word32 inKeySz,
Vanger 0:b86d15c6ba29 735 const byte* salt, word32 saltSz,
Vanger 0:b86d15c6ba29 736 const byte* info, word32 infoSz,
Vanger 0:b86d15c6ba29 737 byte* out, word32 outSz)
Vanger 0:b86d15c6ba29 738 {
Vanger 0:b86d15c6ba29 739 Hmac myHmac;
Vanger 0:b86d15c6ba29 740 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 741 byte* tmp;
Vanger 0:b86d15c6ba29 742 byte* prk;
Vanger 0:b86d15c6ba29 743 #else
Vanger 0:b86d15c6ba29 744 byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper and T */
Vanger 0:b86d15c6ba29 745 byte prk[MAX_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 746 #endif
Vanger 0:b86d15c6ba29 747 const byte* localSalt; /* either points to user input or tmp */
Vanger 0:b86d15c6ba29 748 int hashSz = GetHashSizeByType(type);
Vanger 0:b86d15c6ba29 749 word32 outIdx = 0;
Vanger 0:b86d15c6ba29 750 byte n = 0x1;
Vanger 0:b86d15c6ba29 751 int ret;
Vanger 0:b86d15c6ba29 752
Vanger 0:b86d15c6ba29 753 if (hashSz < 0)
Vanger 0:b86d15c6ba29 754 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 755
Vanger 0:b86d15c6ba29 756 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 757 tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 758 if (tmp == NULL)
Vanger 0:b86d15c6ba29 759 return MEMORY_E;
Vanger 0:b86d15c6ba29 760
Vanger 0:b86d15c6ba29 761 prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 762 if (prk == NULL) {
Vanger 0:b86d15c6ba29 763 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 764 return MEMORY_E;
Vanger 0:b86d15c6ba29 765 }
Vanger 0:b86d15c6ba29 766 #endif
Vanger 0:b86d15c6ba29 767
Vanger 0:b86d15c6ba29 768 localSalt = salt;
Vanger 0:b86d15c6ba29 769 if (localSalt == NULL) {
Vanger 0:b86d15c6ba29 770 XMEMSET(tmp, 0, hashSz);
Vanger 0:b86d15c6ba29 771 localSalt = tmp;
Vanger 0:b86d15c6ba29 772 saltSz = hashSz;
Vanger 0:b86d15c6ba29 773 }
Vanger 0:b86d15c6ba29 774
Vanger 0:b86d15c6ba29 775 do {
Vanger 0:b86d15c6ba29 776 ret = HmacSetKey(&myHmac, type, localSalt, saltSz);
Vanger 0:b86d15c6ba29 777 if (ret != 0)
Vanger 0:b86d15c6ba29 778 break;
Vanger 0:b86d15c6ba29 779 ret = HmacUpdate(&myHmac, inKey, inKeySz);
Vanger 0:b86d15c6ba29 780 if (ret != 0)
Vanger 0:b86d15c6ba29 781 break;
Vanger 0:b86d15c6ba29 782 ret = HmacFinal(&myHmac, prk);
Vanger 0:b86d15c6ba29 783 } while (0);
Vanger 0:b86d15c6ba29 784
Vanger 0:b86d15c6ba29 785 if (ret == 0) {
Vanger 0:b86d15c6ba29 786 while (outIdx < outSz) {
Vanger 0:b86d15c6ba29 787 int tmpSz = (n == 1) ? 0 : hashSz;
Vanger 0:b86d15c6ba29 788 word32 left = outSz - outIdx;
Vanger 0:b86d15c6ba29 789
Vanger 0:b86d15c6ba29 790 ret = HmacSetKey(&myHmac, type, prk, hashSz);
Vanger 0:b86d15c6ba29 791 if (ret != 0)
Vanger 0:b86d15c6ba29 792 break;
Vanger 0:b86d15c6ba29 793 ret = HmacUpdate(&myHmac, tmp, tmpSz);
Vanger 0:b86d15c6ba29 794 if (ret != 0)
Vanger 0:b86d15c6ba29 795 break;
Vanger 0:b86d15c6ba29 796 ret = HmacUpdate(&myHmac, info, infoSz);
Vanger 0:b86d15c6ba29 797 if (ret != 0)
Vanger 0:b86d15c6ba29 798 break;
Vanger 0:b86d15c6ba29 799 ret = HmacUpdate(&myHmac, &n, 1);
Vanger 0:b86d15c6ba29 800 if (ret != 0)
Vanger 0:b86d15c6ba29 801 break;
Vanger 0:b86d15c6ba29 802 ret = HmacFinal(&myHmac, tmp);
Vanger 0:b86d15c6ba29 803 if (ret != 0)
Vanger 0:b86d15c6ba29 804 break;
Vanger 0:b86d15c6ba29 805
Vanger 0:b86d15c6ba29 806 left = min(left, (word32)hashSz);
Vanger 0:b86d15c6ba29 807 XMEMCPY(out+outIdx, tmp, left);
Vanger 0:b86d15c6ba29 808
Vanger 0:b86d15c6ba29 809 outIdx += hashSz;
Vanger 0:b86d15c6ba29 810 n++;
Vanger 0:b86d15c6ba29 811 }
Vanger 0:b86d15c6ba29 812 }
Vanger 0:b86d15c6ba29 813
Vanger 0:b86d15c6ba29 814 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 815 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 816 XFREE(prk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 817 #endif
Vanger 0:b86d15c6ba29 818
Vanger 0:b86d15c6ba29 819 return ret;
Vanger 0:b86d15c6ba29 820 }
Vanger 0:b86d15c6ba29 821
Vanger 0:b86d15c6ba29 822 #endif /* HAVE_HKDF */
Vanger 0:b86d15c6ba29 823
Vanger 0:b86d15c6ba29 824 #endif /* NO_HMAC */
Vanger 0:b86d15c6ba29 825