This is a port of cyaSSL 2.7.0.
Dependents: CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet
hmac.c
00001 /* hmac.c 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifndef NO_HMAC 00029 00030 #include <cyassl/ctaocrypt/hmac.h> 00031 #include <cyassl/ctaocrypt/ctaoerror2.h> 00032 00033 00034 #ifdef HAVE_CAVIUM 00035 static void HmacCaviumFinal(Hmac* hmac, byte* hash); 00036 static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length); 00037 static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, 00038 word32 length); 00039 #endif 00040 00041 static int InitHmac(Hmac* hmac, int type) 00042 { 00043 hmac->innerHashKeyed = 0; 00044 hmac->macType = (byte)type; 00045 00046 if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 00047 || type == SHA512)) 00048 return BAD_FUNC_ARG; 00049 00050 switch (type) { 00051 #ifndef NO_MD5 00052 case MD5: 00053 InitMd5(&hmac->hash.md5); 00054 break; 00055 #endif 00056 00057 #ifndef NO_SHA 00058 case SHA: 00059 InitSha(&hmac->hash.sha); 00060 break; 00061 #endif 00062 00063 #ifndef NO_SHA256 00064 case SHA256: 00065 InitSha256(&hmac->hash.sha256); 00066 break; 00067 #endif 00068 00069 #ifdef CYASSL_SHA384 00070 case SHA384: 00071 InitSha384(&hmac->hash.sha384); 00072 break; 00073 #endif 00074 00075 #ifdef CYASSL_SHA512 00076 case SHA512: 00077 InitSha512(&hmac->hash.sha512); 00078 break; 00079 #endif 00080 00081 default: 00082 break; 00083 } 00084 00085 return 0; 00086 } 00087 00088 00089 void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) 00090 { 00091 byte* ip = (byte*) hmac->ipad; 00092 byte* op = (byte*) hmac->opad; 00093 word32 i, hmac_block_size = 0; 00094 00095 #ifdef HAVE_CAVIUM 00096 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00097 return HmacCaviumSetKey(hmac, type, key, length); 00098 #endif 00099 00100 InitHmac(hmac, type); 00101 00102 switch (hmac->macType) { 00103 #ifndef NO_MD5 00104 case MD5: 00105 { 00106 hmac_block_size = MD5_BLOCK_SIZE; 00107 if (length <= MD5_BLOCK_SIZE) { 00108 XMEMCPY(ip, key, length); 00109 } 00110 else { 00111 Md5Update(&hmac->hash.md5, key, length); 00112 Md5Final(&hmac->hash.md5, ip); 00113 length = MD5_DIGEST_SIZE; 00114 } 00115 } 00116 break; 00117 #endif 00118 00119 #ifndef NO_SHA 00120 case SHA: 00121 { 00122 hmac_block_size = SHA_BLOCK_SIZE; 00123 if (length <= SHA_BLOCK_SIZE) { 00124 XMEMCPY(ip, key, length); 00125 } 00126 else { 00127 ShaUpdate(&hmac->hash.sha, key, length); 00128 ShaFinal(&hmac->hash.sha, ip); 00129 length = SHA_DIGEST_SIZE; 00130 } 00131 } 00132 break; 00133 #endif 00134 00135 #ifndef NO_SHA256 00136 case SHA256: 00137 { 00138 hmac_block_size = SHA256_BLOCK_SIZE; 00139 if (length <= SHA256_BLOCK_SIZE) { 00140 XMEMCPY(ip, key, length); 00141 } 00142 else { 00143 Sha256Update(&hmac->hash.sha256, key, length); 00144 Sha256Final(&hmac->hash.sha256, ip); 00145 length = SHA256_DIGEST_SIZE; 00146 } 00147 } 00148 break; 00149 #endif 00150 00151 #ifdef CYASSL_SHA384 00152 case SHA384: 00153 { 00154 hmac_block_size = SHA384_BLOCK_SIZE; 00155 if (length <= SHA384_BLOCK_SIZE) { 00156 XMEMCPY(ip, key, length); 00157 } 00158 else { 00159 Sha384Update(&hmac->hash.sha384, key, length); 00160 Sha384Final(&hmac->hash.sha384, ip); 00161 length = SHA384_DIGEST_SIZE; 00162 } 00163 } 00164 break; 00165 #endif 00166 00167 #ifdef CYASSL_SHA512 00168 case SHA512: 00169 { 00170 hmac_block_size = SHA512_BLOCK_SIZE; 00171 if (length <= SHA512_BLOCK_SIZE) { 00172 XMEMCPY(ip, key, length); 00173 } 00174 else { 00175 Sha512Update(&hmac->hash.sha512, key, length); 00176 Sha512Final(&hmac->hash.sha512, ip); 00177 length = SHA512_DIGEST_SIZE; 00178 } 00179 } 00180 break; 00181 #endif 00182 00183 default: 00184 break; 00185 } 00186 if (length < hmac_block_size) 00187 XMEMSET(ip + length, 0, hmac_block_size - length); 00188 00189 for(i = 0; i < hmac_block_size; i++) { 00190 op[i] = ip[i] ^ OPAD; 00191 ip[i] ^= IPAD; 00192 } 00193 } 00194 00195 00196 static void HmacKeyInnerHash(Hmac* hmac) 00197 { 00198 switch (hmac->macType) { 00199 #ifndef NO_MD5 00200 case MD5: 00201 Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); 00202 break; 00203 #endif 00204 00205 #ifndef NO_SHA 00206 case SHA: 00207 ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE); 00208 break; 00209 #endif 00210 00211 #ifndef NO_SHA256 00212 case SHA256: 00213 Sha256Update(&hmac->hash.sha256, 00214 (byte*) hmac->ipad, SHA256_BLOCK_SIZE); 00215 break; 00216 #endif 00217 00218 #ifdef CYASSL_SHA384 00219 case SHA384: 00220 Sha384Update(&hmac->hash.sha384, 00221 (byte*) hmac->ipad, SHA384_BLOCK_SIZE); 00222 break; 00223 #endif 00224 00225 #ifdef CYASSL_SHA512 00226 case SHA512: 00227 Sha512Update(&hmac->hash.sha512, 00228 (byte*) hmac->ipad, SHA512_BLOCK_SIZE); 00229 break; 00230 #endif 00231 00232 default: 00233 break; 00234 } 00235 00236 hmac->innerHashKeyed = 1; 00237 } 00238 00239 00240 void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) 00241 { 00242 #ifdef HAVE_CAVIUM 00243 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00244 return HmacCaviumUpdate(hmac, msg, length); 00245 #endif 00246 00247 if (!hmac->innerHashKeyed) 00248 HmacKeyInnerHash(hmac); 00249 00250 switch (hmac->macType) { 00251 #ifndef NO_MD5 00252 case MD5: 00253 Md5Update(&hmac->hash.md5, msg, length); 00254 break; 00255 #endif 00256 00257 #ifndef NO_SHA 00258 case SHA: 00259 ShaUpdate(&hmac->hash.sha, msg, length); 00260 break; 00261 #endif 00262 00263 #ifndef NO_SHA256 00264 case SHA256: 00265 Sha256Update(&hmac->hash.sha256, msg, length); 00266 break; 00267 #endif 00268 00269 #ifdef CYASSL_SHA384 00270 case SHA384: 00271 Sha384Update(&hmac->hash.sha384, msg, length); 00272 break; 00273 #endif 00274 00275 #ifdef CYASSL_SHA512 00276 case SHA512: 00277 Sha512Update(&hmac->hash.sha512, msg, length); 00278 break; 00279 #endif 00280 00281 default: 00282 break; 00283 } 00284 00285 } 00286 00287 00288 void HmacFinal(Hmac* hmac, byte* hash) 00289 { 00290 #ifdef HAVE_CAVIUM 00291 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00292 return HmacCaviumFinal(hmac, hash); 00293 #endif 00294 00295 if (!hmac->innerHashKeyed) 00296 HmacKeyInnerHash(hmac); 00297 00298 switch (hmac->macType) { 00299 #ifndef NO_MD5 00300 case MD5: 00301 { 00302 Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); 00303 00304 Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); 00305 Md5Update(&hmac->hash.md5, 00306 (byte*) hmac->innerHash, MD5_DIGEST_SIZE); 00307 00308 Md5Final(&hmac->hash.md5, hash); 00309 } 00310 break; 00311 #endif 00312 00313 #ifndef NO_SHA 00314 case SHA: 00315 { 00316 ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); 00317 00318 ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE); 00319 ShaUpdate(&hmac->hash.sha, 00320 (byte*) hmac->innerHash, SHA_DIGEST_SIZE); 00321 00322 ShaFinal(&hmac->hash.sha, hash); 00323 } 00324 break; 00325 #endif 00326 00327 #ifndef NO_SHA256 00328 case SHA256: 00329 { 00330 Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); 00331 00332 Sha256Update(&hmac->hash.sha256, 00333 (byte*) hmac->opad, SHA256_BLOCK_SIZE); 00334 Sha256Update(&hmac->hash.sha256, 00335 (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); 00336 00337 Sha256Final(&hmac->hash.sha256, hash); 00338 } 00339 break; 00340 #endif 00341 00342 #ifdef CYASSL_SHA384 00343 case SHA384: 00344 { 00345 Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); 00346 00347 Sha384Update(&hmac->hash.sha384, 00348 (byte*) hmac->opad, SHA384_BLOCK_SIZE); 00349 Sha384Update(&hmac->hash.sha384, 00350 (byte*) hmac->innerHash, SHA384_DIGEST_SIZE); 00351 00352 Sha384Final(&hmac->hash.sha384, hash); 00353 } 00354 break; 00355 #endif 00356 00357 #ifdef CYASSL_SHA512 00358 case SHA512: 00359 { 00360 Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash); 00361 00362 Sha512Update(&hmac->hash.sha512, 00363 (byte*) hmac->opad, SHA512_BLOCK_SIZE); 00364 Sha512Update(&hmac->hash.sha512, 00365 (byte*) hmac->innerHash, SHA512_DIGEST_SIZE); 00366 00367 Sha512Final(&hmac->hash.sha512, hash); 00368 } 00369 break; 00370 #endif 00371 00372 default: 00373 break; 00374 } 00375 00376 hmac->innerHashKeyed = 0; 00377 } 00378 00379 00380 #ifdef HAVE_CAVIUM 00381 00382 /* Initiliaze Hmac for use with Nitrox device */ 00383 int HmacInitCavium(Hmac* hmac, int devId) 00384 { 00385 if (hmac == NULL) 00386 return -1; 00387 00388 if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0) 00389 return -1; 00390 00391 hmac->keyLen = 0; 00392 hmac->dataLen = 0; 00393 hmac->type = 0; 00394 hmac->devId = devId; 00395 hmac->magic = CYASSL_HMAC_CAVIUM_MAGIC; 00396 hmac->data = NULL; /* buffered input data */ 00397 00398 hmac->innerHashKeyed = 0; 00399 00400 return 0; 00401 } 00402 00403 00404 /* Free Hmac from use with Nitrox device */ 00405 void HmacFreeCavium(Hmac* hmac) 00406 { 00407 if (hmac == NULL) 00408 return; 00409 00410 CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId); 00411 hmac->magic = 0; 00412 XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); 00413 hmac->data = NULL; 00414 } 00415 00416 00417 static void HmacCaviumFinal(Hmac* hmac, byte* hash) 00418 { 00419 word32 requestId; 00420 00421 if (CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen, 00422 (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId, 00423 hmac->devId) != 0) { 00424 CYASSL_MSG("Cavium Hmac failed"); 00425 } 00426 hmac->innerHashKeyed = 0; /* tell update to start over if used again */ 00427 } 00428 00429 00430 static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length) 00431 { 00432 word16 add = (word16)length; 00433 word32 total; 00434 byte* tmp; 00435 00436 if (length > CYASSL_MAX_16BIT) { 00437 CYASSL_MSG("Too big msg for cavium hmac"); 00438 return; 00439 } 00440 00441 if (hmac->innerHashKeyed == 0) { /* starting new */ 00442 hmac->dataLen = 0; 00443 hmac->innerHashKeyed = 1; 00444 } 00445 00446 total = add + hmac->dataLen; 00447 if (total > CYASSL_MAX_16BIT) { 00448 CYASSL_MSG("Too big msg for cavium hmac"); 00449 return; 00450 } 00451 00452 tmp = XMALLOC(hmac->dataLen + add, NULL,DYNAMIC_TYPE_CAVIUM_TMP); 00453 if (tmp == NULL) { 00454 CYASSL_MSG("Out of memory for cavium update"); 00455 return; 00456 } 00457 if (hmac->dataLen) 00458 XMEMCPY(tmp, hmac->data, hmac->dataLen); 00459 XMEMCPY(tmp + hmac->dataLen, msg, add); 00460 00461 hmac->dataLen += add; 00462 XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); 00463 hmac->data = tmp; 00464 } 00465 00466 00467 static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, 00468 word32 length) 00469 { 00470 hmac->macType = (byte)type; 00471 if (type == MD5) 00472 hmac->type = MD5_TYPE; 00473 else if (type == SHA) 00474 hmac->type = SHA1_TYPE; 00475 else if (type == SHA256) 00476 hmac->type = SHA256_TYPE; 00477 else { 00478 CYASSL_MSG("unsupported cavium hmac type"); 00479 } 00480 00481 hmac->innerHashKeyed = 0; /* should we key Startup flag */ 00482 00483 hmac->keyLen = (word16)length; 00484 /* store key in ipad */ 00485 XMEMCPY(hmac->ipad, key, length); 00486 } 00487 00488 #endif /* HAVE_CAVIUM */ 00489 00490 #endif /* NO_HMAC */ 00491
Generated on Tue Jul 12 2022 20:44:50 by 1.7.2