/* * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "cc_pal_mem.h" #include "cc_common_math.h" #include "pki.h" #include "pka_ec_wrst.h" #include "pka_error.h" #include "pki_dbg.h" /* temp buffers used for debugging of PKA operations */ #if defined PKA_DEBUG && defined DEBUG uint32_t tempRes[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS]; uint32_t tempRes1[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS]; /*********** PkiDbgPrintReg function **********************/ /** * @brief The function prints label and PKA register as big endian bytes array. * * @author reuvenl (8/25/2013) * * @return None */ void PkiDbgPrintReg(const char* label, /*!< [in] Label string. */ const uint32_t reg) /*!< [in] Register virt. pointer. */ { uint32_t tmp[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS] = {0}; uint32_t sizeBits; uint32_t sizeBytes; uint32_t sizeWords; int32_t i; if (reg > PKA_REG_T1) { PKA_PRINTF("Can't print reg %d, reg is too big \n", reg); exit(1); } sizeBits = PkaGetRegEffectiveSizeInBits(reg); sizeBytes = CALC_FULL_BYTES(sizeBits); sizeWords = CALC_FULL_32BIT_WORDS(sizeBits); if ((sizeBytes > sizeof(tmp)) || ((sizeBits == 0) && (reg < PKA_REG_T0))) { PKA_PRINTF("Can't print reg %d, size in %d\n", reg, sizeBytes); } PkaCopyDataFromPkaReg(tmp, sizeWords, reg); PKA_PRINTF("%s [%d] ", label, sizeBits); for (i=(sizeBytes - 1); i>=0; i--) { PKA_PRINTF("%02X", ((uint8_t*)tmp)[i] & 0xFF); } PKA_PRINTF("\n"); } /*********** PkiDbgPrintUint32BuffAsNum function **********************/ /** * @brief This The function prints the label and 32-bit words buffer (LS-word is * a left most) as a big hexadecimal number (MS-digit is a left most). * * @author reuvenl (8/25/2013) * * @return None */ void PkiDbgPrintUint32BuffAsNum(const char *label, /*!< [in] Label string. */ const uint32_t *pBuf, /*!< [in] 32-bit words buffer to print. */ uint32_t sizeWords) /*!< [in] size of pBuff in 32-bit words. */ { uint32_t sizeBits; int32_t i; sizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(pBuf, sizeWords); PKA_PRINTF("%s [%d] ", label, sizeBits); for (i=(sizeWords - 1); i>=0; i--) { PKA_PRINTF("%08X", pBuf[i]); } PKA_PRINTF("\n"); } /*********** PkiDbgPrintUint8BuffAsNum function **********************/ /** * @brief This The function prints the label and bytes array (LS-byte is * a left most) as a big hexadecimal number (MS-digit is a left most). * * @author reuvenl (14/02/2016) * * @return None */ void PkiDbgPrintUint8BuffAsNum(const char *label, /*!< [in] Label string. */ const uint8_t *pBuf, /*!< [in] 32-bit words buffer to print. */ uint32_t sizeBytes) /*!< [in] size of pBuff in 32-bit words. */ { uint32_t sizeBits; int32_t i; sizeBits = CC_CommonGetBytesCounterEffectiveSizeInBits(pBuf, sizeBytes); PKA_PRINTF("%s [%d] ", label, sizeBits); for (i=(sizeBytes - 1); i>=0; i--) { PKA_PRINTF("%02X", pBuf[i]); } PKA_PRINTF("\n"); } /*********** PkiDbgPrintUintBuf function **********************/ /** * @brief This The function prints the label and bytes array as string. * * @author reuvenl (14/02/2016) * * @return None */ void PkiDbgPrintUint8Buff(const char *label, /*!< [in] Label string. */ const uint8_t *pBuf, /*!< [in] 32-bit words buffer to print. */ uint32_t sizeBytes) /*!< [in] size of pBuff in 32-bit words. */ { uint32_t sizeBits; uint32_t i; sizeBits = CC_CommonGetBytesCounterEffectiveSizeInBits(pBuf, sizeBytes); PKA_PRINTF("%s [%d] ", label, sizeBits); for (i=0; i PKA_MAX_OPCODE) { Error = PKA_ILLEGAL_OPCODE_ERROR; goto End; } if (lenId >= LEN_ID_MAX) { Error = PKA_ILLEGAL_OPERAND_LEN_ERROR; goto End; } if (isAImmed > 1 || isBImmed > 1 || ResDiscard > 1) { Error = PKA_ILLEGAL_OPERAND_TYPE_ERROR; goto End; } if ((OpA > 31) || (OpB > 31) || (Res > 31) || (Tag > 31)) { Error = PKA_ILLEGAL_OPERAND_ERROR; goto End; } /* for ModInv and Div operation check, that modulus or divider are not 0 */ if (Opcode == PKA_OPCODE_ID_MODINV || Opcode == PKA_OPCODE_ID_DIVISION) { int8_t OpT; /* number of register to test its Value = 0 */ /* Set OpT: 0 - for ModInv, OpB - for Div */ if (Opcode == PKA_OPCODE_ID_MODINV) { Error = PKA_MODULUS_IS_NULL_ERROR; OpT = 0; } else { Error = PKA_DIVIDER_IS_NULL_ERROR; OpT = OpB; } /* Create full opcode word for add immediate 0 operation */ FullOpCode = PKA_SET_FULL_OPCODE(PKA_OPCODE_ID_ADD, lenId,0/*isAImmed*/,OpT/*N*/,1,0/*imm 0*/,1/*ResDiscard*/,0/*dumm*/,Tag); /* write full opcode into PKA OPCODE register */ CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL,OPCODE), FullOpCode); /* test zero bit of STATUS register */ PKA_GET_STATUS_ALU_OUT_ZERO(status); if (status == 1) goto End; else Error = CC_OK; } /* for ModInv operation check, that OpB is odd, else return Error (can't calculate, the user must use other function) */ if (Opcode == PKA_OPCODE_ID_MODINV) { /* Create full opcode word for Test bit 0 operation */ FullOpCode = PKA_SET_FULL_OPCODE(PKA_OPCODE_ID_AND, lenId, 0/*isAImmed*/, 0/*N*/, 1, 1/*imm 1*/, 1/*ResDiscard*/, 0/*dumm*/, Tag); /* write full opcode into PKA OPCODE register */ CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, OPCODE), FullOpCode); /* test zero bit of STATUS register */ PKA_GET_STATUS_ALU_OUT_ZERO(status); if (status == 1) { Error = PKA_MOD_EVEN_USE_OTHER_FUNC_ERROR; goto End; } } /*************************************************/ /* main PKI operation of this function */ /*************************************************/ FullOpCode = PKA_SET_FULL_OPCODE(Opcode, lenId, isAImmed, OpA, isBImmed, OpB, ResDiscard, Res, Tag); PKA_WAIT_ON_PKA_PIPE_READY(); CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, OPCODE), FullOpCode); /*************************************************/ /* finishing operations for different cases */ /*************************************************/ if (Opcode == PKA_OPCODE_ID_DIVISION) { /* for Div operation check, that OpB != 0, else return Error */ PKA_GET_STATUS_DIV_BY_ZERO(status); if (status == 1) { Error = PKA_DIVIDER_IS_NULL_ERROR; goto End; } } /* wait for PKA done bit */ PKA_WAIT_ON_PKA_DONE(); /* if operation Tag = Print, then copy result into tempRes buffer */ if (1/*Tag == PKA_TAG_DebugPtint*/ && ResDiscard == 0 && Opcode != PKA_OPCODE_ID_TERMINATE && Opcode != PKA_OPCODE_ID_SEPINT) { CC_PalMemSetZero(tempRes, sizeof(tempRes)); PkaCopyDataFromPkaReg(tempRes/*dst_ptr*/, RegSizeWords, Res/*srcReg*/); if (Opcode == PKA_OPCODE_ID_DIVISION || Opcode == PKA_OPCODE_ID_MODINV) { if (Opcode == PKA_OPCODE_ID_DIVISION) OpPrint = OpA; else OpPrint = OpB; PkaCopyDataFromPkaReg(tempRes1/*dst_ptr*/, RegSizeWords, OpPrint/*srcReg*/); } } End: return Error; } #endif /* #if PKA_EXEC_OP_DEBUG */