Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
cmac.c
00001 /* cmac.c 00002 * 00003 * Copyright (C) 2006-2017 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL 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 * wolfSSL 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfcrypt/settings.h> 00028 00029 #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) 00030 00031 #if defined(HAVE_FIPS) && \ 00032 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) 00033 00034 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 00035 #define FIPS_NO_WRAPPERS 00036 00037 #ifdef USE_WINDOWS_API 00038 #pragma code_seg(".fipsA$n") 00039 #pragma const_seg(".fipsB$n") 00040 #endif 00041 #endif 00042 00043 #ifdef NO_INLINE 00044 #include <wolfcrypt/misc.h> 00045 #else 00046 #define WOLFSSL_MISC_INCLUDED 00047 #include <wolfcrypt/src/misc.c> 00048 #endif 00049 00050 #include <wolfcrypt/error-crypt.h> 00051 #include <wolfcrypt/aes.h> 00052 #include <wolfcrypt/cmac.h> 00053 00054 00055 static void ShiftAndXorRb(byte* out, byte* in) 00056 { 00057 int i, j, xorRb; 00058 int mask = 0, last = 0; 00059 byte Rb = 0x87; 00060 00061 xorRb = (in[0] & 0x80) != 0; 00062 00063 for (i = 1, j = AES_BLOCK_SIZE - 1; i <= AES_BLOCK_SIZE; i++, j--) { 00064 last = (in[j] & 0x80) ? 1 : 0; 00065 out[j] = (byte)((in[j] << 1) | mask); 00066 mask = last; 00067 if (xorRb) { 00068 out[j] ^= Rb; 00069 Rb = 0; 00070 } 00071 } 00072 } 00073 00074 00075 int wc_InitCmac(Cmac* cmac, const byte* key, word32 keySz, 00076 int type, void* unused) 00077 { 00078 int ret; 00079 00080 (void)unused; 00081 00082 if (cmac == NULL || key == NULL || keySz == 0 || type != WC_CMAC_AES) 00083 return BAD_FUNC_ARG; 00084 00085 XMEMSET(cmac, 0, sizeof(Cmac)); 00086 ret = wc_AesSetKey(&cmac->aes, key, keySz, NULL, AES_ENCRYPTION); 00087 if (ret == 0) { 00088 byte l[AES_BLOCK_SIZE]; 00089 00090 XMEMSET(l, 0, AES_BLOCK_SIZE); 00091 wc_AesEncryptDirect(&cmac->aes, l, l); 00092 ShiftAndXorRb(cmac->k1, l); 00093 ShiftAndXorRb(cmac->k2, cmac->k1); 00094 ForceZero(l, AES_BLOCK_SIZE); 00095 } 00096 return ret; 00097 } 00098 00099 00100 int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz) 00101 { 00102 if ((cmac == NULL) || (in == NULL && inSz != 0)) 00103 return BAD_FUNC_ARG; 00104 00105 while (inSz != 0) { 00106 word32 add = min(inSz, AES_BLOCK_SIZE - cmac->bufferSz); 00107 XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add); 00108 00109 cmac->bufferSz += add; 00110 in += add; 00111 inSz -= add; 00112 00113 if (cmac->bufferSz == AES_BLOCK_SIZE && inSz != 0) { 00114 if (cmac->totalSz != 0) 00115 xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE); 00116 wc_AesEncryptDirect(&cmac->aes, 00117 cmac->digest, 00118 cmac->buffer); 00119 cmac->totalSz += AES_BLOCK_SIZE; 00120 cmac->bufferSz = 0; 00121 } 00122 } 00123 00124 return 0; 00125 } 00126 00127 00128 int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) 00129 { 00130 const byte* subKey; 00131 00132 if (cmac == NULL || out == NULL || outSz == NULL) 00133 return BAD_FUNC_ARG; 00134 00135 if (*outSz < WC_CMAC_TAG_MIN_SZ || *outSz > WC_CMAC_TAG_MAX_SZ) 00136 return BUFFER_E; 00137 00138 if (cmac->bufferSz == AES_BLOCK_SIZE) { 00139 subKey = cmac->k1; 00140 } 00141 else { 00142 word32 remainder = AES_BLOCK_SIZE - cmac->bufferSz; 00143 00144 if (remainder == 0) 00145 remainder = AES_BLOCK_SIZE; 00146 00147 if (remainder > 1) 00148 XMEMSET(cmac->buffer + AES_BLOCK_SIZE - remainder, 0, remainder); 00149 cmac->buffer[AES_BLOCK_SIZE - remainder] = 0x80; 00150 subKey = cmac->k2; 00151 } 00152 xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE); 00153 xorbuf(cmac->buffer, subKey, AES_BLOCK_SIZE); 00154 wc_AesEncryptDirect(&cmac->aes, cmac->digest, cmac->buffer); 00155 00156 XMEMCPY(out, cmac->digest, *outSz); 00157 00158 ForceZero(cmac, sizeof(Cmac)); 00159 00160 return 0; 00161 } 00162 00163 00164 int wc_AesCmacGenerate(byte* out, word32* outSz, 00165 const byte* in, word32 inSz, 00166 const byte* key, word32 keySz) 00167 { 00168 Cmac cmac; 00169 int ret; 00170 00171 if (out == NULL || (in == NULL && inSz > 0) || key == NULL || keySz == 0) 00172 return BAD_FUNC_ARG; 00173 00174 ret = wc_InitCmac(&cmac, key, keySz, WC_CMAC_AES, NULL); 00175 if (ret != 0) 00176 return ret; 00177 00178 ret = wc_CmacUpdate(&cmac, in, inSz); 00179 if (ret != 0) 00180 return ret; 00181 00182 ret = wc_CmacFinal(&cmac, out, outSz); 00183 if (ret != 0) 00184 return ret; 00185 00186 return 0; 00187 } 00188 00189 00190 int wc_AesCmacVerify(const byte* check, word32 checkSz, 00191 const byte* in, word32 inSz, 00192 const byte* key, word32 keySz) 00193 { 00194 byte a[AES_BLOCK_SIZE]; 00195 word32 aSz = sizeof(a); 00196 int result; 00197 int compareRet; 00198 00199 if (check == NULL || checkSz == 0 || (in == NULL && inSz != 0) || 00200 key == NULL || keySz == 0) 00201 00202 return BAD_FUNC_ARG; 00203 00204 XMEMSET(a, 0, aSz); 00205 result = wc_AesCmacGenerate(a, &aSz, in, inSz, key, keySz); 00206 compareRet = ConstantCompare(check, a, min(checkSz, aSz)); 00207 00208 if (result == 0) 00209 result = compareRet ? 1 : 0; 00210 00211 return result; 00212 } 00213 00214 00215 #endif /* WOLFSSL_CMAC && NO_AES && WOLFSSL_AES_DIRECT */ 00216
Generated on Tue Jul 12 2022 16:58:05 by
1.7.2