static int AesAlign16(Aes* aes, byte* out, const byte* in, word32 sz, word32 dir, word32 mode) { wolfSSL_TI_lockCCM() ; ROM_AESReset(AES_BASE); ROM_AESConfigSet(AES_BASE, (aes->keylen | dir | (mode==AES_CFG_MODE_CTR_NOCTR ? AES_CFG_MODE_CTR : mode))); ROM_AESIVSet(AES_BASE, aes->reg); ROM_AESKey1Set(AES_BASE, aes->key, aes->keylen); if((dir == AES_CFG_DIR_DECRYPT)&& (mode == AES_CFG_MODE_CBC)) /* if input and output same will overwrite input iv */ XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); ROM_AESDataProcess(AES_BASE, (uint32_t *)in, (uint32_t *)out, sz); wolfSSL_TI_unlockCCM() ; /* store iv for next call */ if(mode == AES_CFG_MODE_CBC) { if(dir == AES_CFG_DIR_ENCRYPT) XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); else XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); } if(mode == AES_CFG_MODE_CTR) { do { int i ; for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { if (++((byte *)aes->reg)[i]) break ; } sz -= AES_BLOCK_SIZE ; } while((int)sz > 0) ; } return 0 ; }
//***************************************************************************** // // Perform an ECB encryption operation. // //***************************************************************************** bool AESECBEncrypt(uint32_t ui32Keysize, uint32_t *pui32Src, uint32_t *pui32Dst, uint32_t *pui32Key, uint32_t ui32Length) { // // Perform a soft reset. // ROM_AESReset(AES_BASE); // // Configure the AES module. // ROM_AESConfigSet(AES_BASE, (ui32Keysize | AES_CFG_DIR_ENCRYPT | AES_CFG_MODE_ECB)); // // Write the key. // ROM_AESKey1Set(AES_BASE, pui32Key, ui32Keysize); // // Perform the encryption. // ROM_AESDataProcess(AES_BASE, pui32Src, pui32Dst, ui32Length); return(true); }
//***************************************************************************** // // Perform a basic GHASH operation with the hashsubkey and IV. This is // used to get Y0 when the IV is not 96 bits. To use this GCM mode, the // operation direction must not be set and the counter should be disabled. // //***************************************************************************** void AESGHASH(uint32_t ui32Keysize, uint32_t *pui32HashSubkey, uint32_t *pui32IV, uint32_t ui32IVLength, uint32_t *pui32Result) { uint32_t ui32Count; // // Perform a soft reset. // ROM_AESReset(AES_BASE); // // Configure the AES module. // ROM_AESConfigSet(AES_BASE, (ui32Keysize | AES_CFG_MODE_GCM_HLY0ZERO)); // // Set the hash subkey. // ROM_AESKey2Set(AES_BASE, pui32HashSubkey, ui32Keysize); // // Write the lengths // ROM_AESLengthSet(AES_BASE, (uint64_t)ui32IVLength); ROM_AESAuthLengthSet(AES_BASE, 0); // // Write the data. // for(ui32Count = 0; ui32Count < ui32IVLength; ui32Count += 16) { // // Write the data registers. // ROM_AESDataWrite(AES_BASE, pui32IV + (ui32Count / 4)); } // // Read the hash tag value. // AESTagRead(AES_BASE, pui32Result); }
//***************************************************************************** // // Perform an CCM decryption operation. // //***************************************************************************** bool AES128CCMDecrypt(uint32_t *pui32Key, uint32_t *pui32Src, uint32_t *pui32Dst, uint32_t ui32DataLength, uint32_t *pui32Nonce, uint32_t ui32NonceLength, uint32_t *pui32AuthData, uint32_t ui32AuthDataLength, uint32_t *pui32Tag, uint32_t ui32TagLength, bool bUseDMA) { uint32_t pui32IV[4], ui32Idx; uint32_t ui32M, ui32L; uint8_t *pui8Nonce, *pui8IV; // // Determine the value of M. It is determined using // the tag length. // if(ui32TagLength == 4) { ui32M = AES_CFG_CCM_M_4; } else if(ui32TagLength == 6) { ui32M = AES_CFG_CCM_M_6; } else if(ui32TagLength == 8) { ui32M = AES_CFG_CCM_M_8; } else if(ui32TagLength == 10) { ui32M = AES_CFG_CCM_M_10; } else if(ui32TagLength == 12) { ui32M = AES_CFG_CCM_M_12; } else if(ui32TagLength == 14) { ui32M = AES_CFG_CCM_M_14; } else if(ui32TagLength == 16) { ui32M = AES_CFG_CCM_M_16; } else { UARTprintf("Unexpected tag length.\n"); return(false); } // // Determine the value of L. This is determined by using // the value of q from the NIST document: n + q = 15 // if(ui32NonceLength == 7) { ui32L = AES_CFG_CCM_L_8; } else if(ui32NonceLength == 8) { ui32L = AES_CFG_CCM_L_7; } else if(ui32NonceLength == 9) { ui32L = AES_CFG_CCM_L_6; } else if(ui32NonceLength == 10) { ui32L = AES_CFG_CCM_L_5; } else if(ui32NonceLength == 11) { ui32L = AES_CFG_CCM_L_4; } else if(ui32NonceLength == 12) { ui32L = AES_CFG_CCM_L_3; } else if(ui32NonceLength == 13) { ui32L = AES_CFG_CCM_L_2; } else if(ui32NonceLength == 14) { ui32L = AES_CFG_CCM_L_1; } else { UARTprintf("Unexpected nonce length.\n"); return(false); } // // Perform a soft reset. // ROM_AESReset(AES_BASE); // // Clear the interrupt flags. // g_bContextInIntFlag = false; g_bDataInIntFlag = false; g_bContextOutIntFlag = false; g_bDataOutIntFlag = false; g_bContextInDMADoneIntFlag = false; g_bDataInDMADoneIntFlag = false; g_bContextOutDMADoneIntFlag = false; g_bDataOutDMADoneIntFlag = false; // // Enable all interrupts. // ROM_AESIntEnable(AES_BASE, (AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT | AES_INT_DATA_IN | AES_INT_DATA_OUT)); // // Configure the AES module. // ROM_AESConfigSet(AES_BASE, (AES_CFG_KEY_SIZE_128BIT | AES_CFG_DIR_DECRYPT | AES_CFG_CTR_WIDTH_128 | AES_CFG_MODE_CCM | ui32L | ui32M)); // // Determine the value to be written in the initial value registers. It is // the concatenation of 5 bits of zero, 3 bits of L, nonce, and the counter // value. First, clear the contents of the IV. // for(ui32Idx = 0; ui32Idx < 4; ui32Idx++) { pui32IV[ui32Idx] = 0; } // // Now find the binary value of L. // if(ui32L == AES_CFG_CCM_L_8) { pui32IV[0] = 0x7; } else if(ui32L == AES_CFG_CCM_L_7) { pui32IV[0] = 0x6; } else if(ui32L == AES_CFG_CCM_L_6) { pui32IV[0] = 0x5; } else if(ui32L == AES_CFG_CCM_L_5) { pui32IV[0] = 0x4; } else if(ui32L == AES_CFG_CCM_L_4) { pui32IV[0] = 0x3; } else if(ui32L == AES_CFG_CCM_L_3) { pui32IV[0] = 0x2; } else if(ui32L == AES_CFG_CCM_L_2) { pui32IV[0] = 0x1; } // // Finally copy the contents of the nonce into the IV. Convert // the pointers to simplify the copying. // pui8Nonce = (uint8_t *)pui32Nonce; pui8IV = (uint8_t *)pui32IV; for(ui32Idx = 0; ui32Idx < ui32NonceLength; ui32Idx++) { pui8IV[ui32Idx + 1] = pui8Nonce[ui32Idx]; } // // Write the initial value. // ROM_AESIVSet(AES_BASE, pui32IV); // // Write the key. // ROM_AESKey1Set(AES_BASE, pui32Key, AES_CFG_KEY_SIZE_128BIT); // // Depending on the argument, perform the decryption // with or without uDMA. // if(bUseDMA) { // // Enable DMA interrupts. // ROM_AESIntEnable(AES_BASE, (AES_INT_DMA_CONTEXT_IN | AES_INT_DMA_DATA_IN | AES_INT_DMA_CONTEXT_OUT | AES_INT_DMA_DATA_OUT)); // // Setup the DMA module to copy auth data in. // ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN); ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_4 | UDMA_DST_PROT_PRIV); ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)pui32AuthData, (void *)(AES_BASE + AES_O_DATA_IN_0), LengthRoundUp(ui32AuthDataLength) / 4); UARTprintf("Data in DMA request enabled.\n"); // // Setup the DMA module to copy the data out. // ROM_uDMAChannelAssign(UDMA_CH15_AES0DOUT); ROM_uDMAChannelAttributeDisable(UDMA_CH15_AES0DOUT, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelControlSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_ARB_4 | UDMA_SRC_PROT_PRIV); ROM_uDMAChannelTransferSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(AES_BASE + AES_O_DATA_IN_0), (void *)pui32Dst, LengthRoundUp(ui32DataLength) / 4); UARTprintf("Data out DMA request enabled.\n"); // // Write the length registers. // ROM_AESLengthSet(AES_BASE, (uint64_t)ui32DataLength); // // Write the auth length registers to start the process. // ROM_AESAuthLengthSet(AES_BASE, ui32AuthDataLength); // // Enable the DMA channels to start the transfers. This must be done after // writing the length to prevent data from copying before the context is // truly ready. // ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN); ROM_uDMAChannelEnable(UDMA_CH15_AES0DOUT); // // Enable DMA requests. // ROM_AESDMAEnable(AES_BASE, AES_DMA_DATA_IN | AES_DMA_DATA_OUT); // // Wait for the data in DMA done interrupt. // while(!g_bDataInDMADoneIntFlag) { } // // Setup the uDMA to copy the plaintext data. // ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN); ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_4 | UDMA_DST_PROT_PRIV); ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)pui32Src, (void *)(AES_BASE + AES_O_DATA_IN_0), LengthRoundUp(ui32DataLength) / 4); ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN); UARTprintf("Data in DMA request enabled.\n"); // // Wait for the data out DMA done interrupt. // while(!g_bDataOutDMADoneIntFlag) { } // // Read the tag out. // ROM_AESTagRead(AES_BASE, pui32Tag); } else { // // Perform the decryption. // ROM_AESDataProcessAuth(AES_BASE, pui32Src, pui32Dst, ui32DataLength, pui32AuthData, ui32AuthDataLength, pui32Tag); } return(true); }
static int AesAuthDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, const byte* nonce, word32 nonceSz, const byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz, int mode) { word32 M, L ; byte *in_a, *in_save ; byte *out_a, *out_save ; byte *authIn_a, *authIn_save ; byte *nonce_a, *nonce_save ; word32 tmpTag[4] ; bool ret ; if(AesAuthArgCheck(aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz, authIn, authInSz, &M, &L) == BAD_FUNC_ARG)return BAD_FUNC_ARG ; /* 16 byte padding */ in_save = NULL ; out_save = NULL ; authIn_save = NULL ; nonce_save = NULL ; if((inSz%16)==0) { in_save = NULL ; in_a = (byte *)in ; out_save = NULL ; out_a = out ; } else { if((in_save = XMALLOC(RoundUp16(inSz), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) { FREE_ALL; return MEMORY_E; } in_a = in_save ; XMEMSET(in_a, 0, RoundUp16(inSz)) ; XMEMCPY(in_a, in, inSz) ; if((out_save = XMALLOC(RoundUp16(inSz), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) { FREE_ALL; return MEMORY_E; } out_a = out_save ; } if((authInSz%16)==0) { authIn_save = NULL ; authIn_a = (byte *)authIn ; } else { if((authIn_save = XMALLOC(RoundUp16(authInSz), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) { FREE_ALL; return MEMORY_E; } authIn_a = authIn_save ; XMEMSET(authIn_a, 0, RoundUp16(authInSz)) ; XMEMCPY(authIn_a, authIn, authInSz) ; } if((nonceSz%16)==0) { nonce_save = NULL ; nonce_a = (byte *)nonce ; } else { if((nonce_save = XMALLOC(RoundUp16(nonceSz), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) { FREE_ALL; return MEMORY_E; } nonce_a = nonce_save ; XMEMSET(nonce_a, 0, RoundUp16(nonceSz)) ; XMEMCPY(nonce_a, nonce, nonceSz) ; } /* do aes-ccm */ AesAuthSetIv(aes, nonce, nonceSz, L, mode) ; ROM_AESReset(AES_BASE); ROM_AESConfigSet(AES_BASE, (aes->keylen | AES_CFG_DIR_DECRYPT | AES_CFG_CTR_WIDTH_128 | mode | ((mode== AES_CFG_MODE_CCM) ? (L | M) : 0 ))) ; ROM_AESIVSet(AES_BASE, aes->reg); ROM_AESKey1Set(AES_BASE, aes->key, aes->keylen); ret = ROM_AESDataProcessAuth(AES_BASE, (unsigned int*)in_a, (unsigned int *)out_a, inSz, (unsigned int*)authIn_a, authInSz, (unsigned int *)tmpTag); if((ret == false) || (XMEMCMP(authTag, tmpTag, authTagSz) != 0)) { XMEMSET(out, 0, inSz) ; ret = false ; } else { XMEMCPY(out, out_a, inSz) ; } FREE_ALL ; return ret==true ? 0 : 1 ; }
//***************************************************************************** // // Perform an GCM decryption operation. // //***************************************************************************** bool AESGCMDecrypt(uint32_t ui32Keysize, uint32_t *pui32Src, uint32_t *pui32Dst, uint32_t ui32Length, uint32_t *pui32Key, uint32_t *pui32IV, uint32_t *pui32AAD, uint32_t ui32AADLength, uint32_t *pui32Tag, bool bUseDMA) { // // Perform a soft reset. // ROM_AESReset(AES_BASE); // // Clear the interrupt flags. // g_bContextInIntFlag = false; g_bDataInIntFlag = false; g_bContextOutIntFlag = false; g_bDataOutIntFlag = false; g_bContextInDMADoneIntFlag = false; g_bDataInDMADoneIntFlag = false; g_bContextOutDMADoneIntFlag = false; g_bDataOutDMADoneIntFlag = false; // // Enable all interrupts. // ROM_AESIntEnable(AES_BASE, (AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT | AES_INT_DATA_IN | AES_INT_DATA_OUT)); // // Wait for the context in flag. // while(!g_bContextInIntFlag) { } // // Configure the AES module. // ROM_AESConfigSet(AES_BASE, (ui32Keysize | AES_CFG_DIR_DECRYPT | AES_CFG_MODE_GCM_HY0CALC)); // // Write the initialization value // ROM_AESIVSet(AES_BASE, pui32IV); // // Write the keys. // ROM_AESKey1Set(AES_BASE, pui32Key, ui32Keysize); // // Depending on the argument, perform the decryption // with or without uDMA. // if(bUseDMA) { // // Enable DMA interrupts. // ROM_AESIntEnable(AES_BASE, (AES_INT_DMA_CONTEXT_IN | AES_INT_DMA_DATA_IN | AES_INT_DMA_CONTEXT_OUT | AES_INT_DMA_DATA_OUT)); if(ui32AADLength != 0) { // // Setup the DMA module to copy auth data in. // ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN); ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_4 | UDMA_DST_PROT_PRIV); ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)pui32AAD, (void *)(AES_BASE + AES_O_DATA_IN_0), LengthRoundUp(ui32AADLength) / 4); UARTprintf("Data in DMA request enabled.\n"); } // // Setup the DMA module to copy the data out. // ROM_uDMAChannelAssign(UDMA_CH15_AES0DOUT); ROM_uDMAChannelAttributeDisable(UDMA_CH15_AES0DOUT, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelControlSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_ARB_4 | UDMA_SRC_PROT_PRIV); ROM_uDMAChannelTransferSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(AES_BASE + AES_O_DATA_IN_0), (void *)pui32Dst, LengthRoundUp(ui32Length) / 4); UARTprintf("Data out DMA request enabled.\n"); // // Write the plaintext length // ROM_AESLengthSet(AES_BASE, (uint64_t)ui32Length); // // Write the auth length registers to start the process. // ROM_AESAuthLengthSet(AES_BASE, ui32AADLength); // // Enable the DMA channels to start the transfers. This must be done after // writing the length to prevent data from copying before the context is // truly ready. // if(ui32AADLength != 0) { ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN); } ROM_uDMAChannelEnable(UDMA_CH15_AES0DOUT); // // Enable DMA requests // ROM_AESDMAEnable(AES_BASE, AES_DMA_DATA_IN | AES_DMA_DATA_OUT); if(ui32AADLength != 0) { // // Wait for the data in DMA done interrupt. // while(!g_bDataInDMADoneIntFlag) { } } if(ui32Length != 0) { // // Setup the uDMA to copy the plaintext data. // ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN); ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_4 | UDMA_DST_PROT_PRIV); ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)pui32Src, (void *)(AES_BASE + AES_O_DATA_IN_0), LengthRoundUp(ui32Length) / 4); ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN); UARTprintf("Data in DMA request enabled.\n"); // // Wait for the data out DMA done interrupt. // while(!g_bDataOutDMADoneIntFlag) { } } // // Read out the tag. // AESTagRead(AES_BASE, pui32Tag); } else { // // Perform the decryption. // ROM_AESDataProcessAuth(AES_BASE, pui32Src, pui32Dst, ui32Length, pui32AAD, ui32AADLength, pui32Tag); } return(true); }