cyassl re-port with cellular comms, PSK test
Dependencies: VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src
hmac.c
00001 /* hmac.c 00002 * 00003 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. 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 #ifndef NO_HMAC 00027 00028 #include <cyassl/ctaocrypt/hmac.h> 00029 #include <cyassl/ctaocrypt/error.h> 00030 00031 00032 #ifdef HAVE_CAVIUM 00033 static void HmacCaviumFinal(Hmac* hmac, byte* hash); 00034 static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length); 00035 static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, 00036 word32 length); 00037 #endif 00038 00039 00040 static int InitHmac(Hmac* hmac, int type) 00041 { 00042 hmac->innerHashKeyed = 0; 00043 hmac->macType = (byte)type; 00044 00045 if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384)) 00046 return BAD_FUNC_ARG; 00047 00048 switch (type) { 00049 #ifndef NO_MD5 00050 case MD5: 00051 InitMd5(&hmac->hash.md5); 00052 break; 00053 #endif 00054 00055 case SHA: 00056 InitSha(&hmac->hash.sha); 00057 break; 00058 00059 #ifndef NO_SHA256 00060 case SHA256: 00061 InitSha256(&hmac->hash.sha256); 00062 break; 00063 #endif 00064 00065 #ifdef CYASSL_SHA384 00066 case SHA384: 00067 InitSha384(&hmac->hash.sha384); 00068 break; 00069 #endif 00070 00071 default: 00072 break; 00073 } 00074 00075 return 0; 00076 } 00077 00078 00079 void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) 00080 { 00081 byte* ip = (byte*) hmac->ipad; 00082 byte* op = (byte*) hmac->opad; 00083 word32 i, hmac_block_size = SHA_BLOCK_SIZE; 00084 00085 #ifdef HAVE_CAVIUM 00086 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00087 return HmacCaviumSetKey(hmac, type, key, length); 00088 #endif 00089 00090 InitHmac(hmac, type); 00091 00092 switch (hmac->macType) { 00093 #ifndef NO_MD5 00094 case MD5: 00095 { 00096 hmac_block_size = MD5_BLOCK_SIZE; 00097 if (length <= MD5_BLOCK_SIZE) { 00098 XMEMCPY(ip, key, length); 00099 } 00100 else { 00101 Md5Update(&hmac->hash.md5, key, length); 00102 Md5Final(&hmac->hash.md5, ip); 00103 length = MD5_DIGEST_SIZE; 00104 } 00105 } 00106 break; 00107 #endif 00108 00109 case SHA: 00110 { 00111 if (length <= SHA_BLOCK_SIZE) { 00112 XMEMCPY(ip, key, length); 00113 } 00114 else { 00115 ShaUpdate(&hmac->hash.sha, key, length); 00116 ShaFinal(&hmac->hash.sha, ip); 00117 length = SHA_DIGEST_SIZE; 00118 } 00119 } 00120 break; 00121 00122 #ifndef NO_SHA256 00123 case SHA256: 00124 { 00125 hmac_block_size = SHA256_BLOCK_SIZE; 00126 if (length <= SHA256_BLOCK_SIZE) { 00127 XMEMCPY(ip, key, length); 00128 } 00129 else { 00130 Sha256Update(&hmac->hash.sha256, key, length); 00131 Sha256Final(&hmac->hash.sha256, ip); 00132 length = SHA256_DIGEST_SIZE; 00133 } 00134 } 00135 break; 00136 #endif 00137 00138 #ifdef CYASSL_SHA384 00139 case SHA384: 00140 { 00141 hmac_block_size = SHA384_BLOCK_SIZE; 00142 if (length <= SHA384_BLOCK_SIZE) { 00143 XMEMCPY(ip, key, length); 00144 } 00145 else { 00146 Sha384Update(&hmac->hash.sha384, key, length); 00147 Sha384Final(&hmac->hash.sha384, ip); 00148 length = SHA384_DIGEST_SIZE; 00149 } 00150 } 00151 break; 00152 #endif 00153 00154 default: 00155 break; 00156 } 00157 XMEMSET(ip + length, 0, hmac_block_size - length); 00158 00159 for(i = 0; i < hmac_block_size; i++) { 00160 op[i] = ip[i] ^ OPAD; 00161 ip[i] ^= IPAD; 00162 } 00163 } 00164 00165 00166 static void HmacKeyInnerHash(Hmac* hmac) 00167 { 00168 switch (hmac->macType) { 00169 #ifndef NO_MD5 00170 case MD5: 00171 Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); 00172 break; 00173 #endif 00174 00175 case SHA: 00176 ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE); 00177 break; 00178 00179 #ifndef NO_SHA256 00180 case SHA256: 00181 Sha256Update(&hmac->hash.sha256, 00182 (byte*) hmac->ipad, SHA256_BLOCK_SIZE); 00183 break; 00184 #endif 00185 00186 #ifdef CYASSL_SHA384 00187 case SHA384: 00188 Sha384Update(&hmac->hash.sha384, 00189 (byte*) hmac->ipad, SHA384_BLOCK_SIZE); 00190 break; 00191 #endif 00192 00193 default: 00194 break; 00195 } 00196 00197 hmac->innerHashKeyed = 1; 00198 } 00199 00200 00201 void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) 00202 { 00203 #ifdef HAVE_CAVIUM 00204 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00205 return HmacCaviumUpdate(hmac, msg, length); 00206 #endif 00207 00208 if (!hmac->innerHashKeyed) 00209 HmacKeyInnerHash(hmac); 00210 00211 switch (hmac->macType) { 00212 #ifndef NO_MD5 00213 case MD5: 00214 Md5Update(&hmac->hash.md5, msg, length); 00215 break; 00216 #endif 00217 00218 case SHA: 00219 ShaUpdate(&hmac->hash.sha, msg, length); 00220 break; 00221 00222 #ifndef NO_SHA256 00223 case SHA256: 00224 Sha256Update(&hmac->hash.sha256, msg, length); 00225 break; 00226 #endif 00227 00228 #ifdef CYASSL_SHA384 00229 case SHA384: 00230 Sha384Update(&hmac->hash.sha384, msg, length); 00231 break; 00232 #endif 00233 00234 default: 00235 break; 00236 } 00237 00238 } 00239 00240 00241 void HmacFinal(Hmac* hmac, byte* hash) 00242 { 00243 #ifdef HAVE_CAVIUM 00244 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00245 return HmacCaviumFinal(hmac, hash); 00246 #endif 00247 00248 if (!hmac->innerHashKeyed) 00249 HmacKeyInnerHash(hmac); 00250 00251 switch (hmac->macType) { 00252 #ifndef NO_MD5 00253 case MD5: 00254 { 00255 Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); 00256 00257 Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); 00258 Md5Update(&hmac->hash.md5, 00259 (byte*) hmac->innerHash, MD5_DIGEST_SIZE); 00260 00261 Md5Final(&hmac->hash.md5, hash); 00262 } 00263 break; 00264 #endif 00265 00266 case SHA: 00267 { 00268 ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); 00269 00270 ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE); 00271 ShaUpdate(&hmac->hash.sha, 00272 (byte*) hmac->innerHash, SHA_DIGEST_SIZE); 00273 00274 ShaFinal(&hmac->hash.sha, hash); 00275 } 00276 break; 00277 00278 #ifndef NO_SHA256 00279 case SHA256: 00280 { 00281 Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); 00282 00283 Sha256Update(&hmac->hash.sha256, 00284 (byte*) hmac->opad, SHA256_BLOCK_SIZE); 00285 Sha256Update(&hmac->hash.sha256, 00286 (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); 00287 00288 Sha256Final(&hmac->hash.sha256, hash); 00289 } 00290 break; 00291 #endif 00292 00293 #ifdef CYASSL_SHA384 00294 case SHA384: 00295 { 00296 Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); 00297 00298 Sha384Update(&hmac->hash.sha384, 00299 (byte*) hmac->opad, SHA384_BLOCK_SIZE); 00300 Sha384Update(&hmac->hash.sha384, 00301 (byte*) hmac->innerHash, SHA384_DIGEST_SIZE); 00302 00303 Sha384Final(&hmac->hash.sha384, hash); 00304 } 00305 break; 00306 #endif 00307 00308 default: 00309 break; 00310 } 00311 00312 hmac->innerHashKeyed = 0; 00313 } 00314 00315 00316 #ifdef HAVE_CAVIUM 00317 00318 /* Initiliaze Hmac for use with Nitrox device */ 00319 int HmacInitCavium(Hmac* hmac, int devId) 00320 { 00321 if (hmac == NULL) 00322 return -1; 00323 00324 if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0) 00325 return -1; 00326 00327 hmac->keyLen = 0; 00328 hmac->dataLen = 0; 00329 hmac->type = 0; 00330 hmac->devId = devId; 00331 hmac->magic = CYASSL_HMAC_CAVIUM_MAGIC; 00332 hmac->data = NULL; /* buffered input data */ 00333 00334 hmac->innerHashKeyed = 0; 00335 00336 return 0; 00337 } 00338 00339 00340 /* Free Hmac from use with Nitrox device */ 00341 void HmacFreeCavium(Hmac* hmac) 00342 { 00343 if (hmac == NULL) 00344 return; 00345 00346 CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId); 00347 hmac->magic = 0; 00348 XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); 00349 hmac->data = NULL; 00350 } 00351 00352 00353 static void HmacCaviumFinal(Hmac* hmac, byte* hash) 00354 { 00355 word32 requestId; 00356 00357 if (CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen, 00358 (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId, 00359 hmac->devId) != 0) { 00360 CYASSL_MSG("Cavium Hmac failed"); 00361 } 00362 hmac->innerHashKeyed = 0; /* tell update to start over if used again */ 00363 } 00364 00365 00366 static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length) 00367 { 00368 word16 add = (word16)length; 00369 word32 total; 00370 byte* tmp; 00371 00372 if (length > CYASSL_MAX_16BIT) { 00373 CYASSL_MSG("Too big msg for cavium hmac"); 00374 return; 00375 } 00376 00377 if (hmac->innerHashKeyed == 0) { /* starting new */ 00378 hmac->dataLen = 0; 00379 hmac->innerHashKeyed = 1; 00380 } 00381 00382 total = add + hmac->dataLen; 00383 if (total > CYASSL_MAX_16BIT) { 00384 CYASSL_MSG("Too big msg for cavium hmac"); 00385 return; 00386 } 00387 00388 tmp = XMALLOC(hmac->dataLen + add, NULL,DYNAMIC_TYPE_CAVIUM_TMP); 00389 if (tmp == NULL) { 00390 CYASSL_MSG("Out of memory for cavium update"); 00391 return; 00392 } 00393 if (hmac->dataLen) 00394 XMEMCPY(tmp, hmac->data, hmac->dataLen); 00395 XMEMCPY(tmp + hmac->dataLen, msg, add); 00396 00397 hmac->dataLen += add; 00398 XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); 00399 hmac->data = tmp; 00400 } 00401 00402 00403 static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, 00404 word32 length) 00405 { 00406 hmac->macType = (byte)type; 00407 if (type == MD5) 00408 hmac->type = MD5_TYPE; 00409 else if (type == SHA) 00410 hmac->type = SHA1_TYPE; 00411 else if (type == SHA256) 00412 hmac->type = SHA256_TYPE; 00413 else { 00414 CYASSL_MSG("unsupported cavium hmac type"); 00415 } 00416 00417 hmac->innerHashKeyed = 0; /* should we key Startup flag */ 00418 00419 hmac->keyLen = (word16)length; 00420 /* store key in ipad */ 00421 XMEMCPY(hmac->ipad, key, length); 00422 } 00423 00424 #endif /* HAVE_CAVIUM */ 00425 00426 #endif /* NO_HMAC */ 00427
Generated on Thu Jul 14 2022 00:25:23 by 1.7.2