/************************************************************************ * The function performs Hash update for data with the size not * aligned to Hash block. * * Note: remBuffSize_ptr - a pointer to the remaining size of the * temp buffer to fill by the data. * ************************************************************************/ static CRYSError_t _DX_KDF_HASH_UnalignUpdate( CRYS_HASHUserContext_t *hashContext_ptr, DxUint8_t *data_ptr, DxUint32_t dataSize, DxUint8_t *buff_ptr, DxUint32_t *remBuffSize_ptr) { CRYSError_t error = CRYS_OK; DxUint32_t tmpSize; DxUint8_t *tmp_ptr; /* set buff_ptr to begin of empty part of temp buffer */ tmp_ptr = buff_ptr + CRYS_HASH_BLOCK_SIZE_IN_BYTES - *remBuffSize_ptr; /* if the temp buffer not empty, append it by the data and update Hash on it */ if(*remBuffSize_ptr < CRYS_HASH_BLOCK_SIZE_IN_BYTES) { if(dataSize > *remBuffSize_ptr) { DX_VOS_FastMemCpy(buff_ptr, data_ptr, *remBuffSize_ptr); /* update on the data in temp buffer */ error = CRYS_HASH_Update( hashContext_ptr, buff_ptr, CRYS_HASH_BLOCK_SIZE_IN_BYTES); if(error != CRYS_OK) return error; /* update pointers and sizes */ data_ptr += *remBuffSize_ptr; dataSize -= *remBuffSize_ptr; *remBuffSize_ptr = CRYS_HASH_BLOCK_SIZE_IN_BYTES; tmp_ptr = buff_ptr; } else if(dataSize < *remBuffSize_ptr) { DX_VOS_FastMemCpy(tmp_ptr, data_ptr, dataSize); *remBuffSize_ptr -= dataSize; return error; } } /* Update Hash on remaining input data */ tmpSize = dataSize % CRYS_HASH_BLOCK_SIZE_IN_BYTES; if (tmpSize > 0) { dataSize -= tmpSize; DX_VOS_FastMemCpy(tmp_ptr, data_ptr + dataSize, tmpSize); *remBuffSize_ptr -= tmpSize; } if(dataSize > 0) error = CRYS_HASH_Update( hashContext_ptr, data_ptr, dataSize); return error; }
/** * @brief This function generates a key pair * * * @param[in] PubKey_ptr - the public key database. * @param[in] PrivKey_ptr - the private key database. * * @return CRYSError_t - On success CRYS_OK is returned, on failure a * value MODULE_* as defined in . */ CRYSError_t LLF_PKI_RSA_GenerateKeyPair( CRYSRSAPubKey_t *PubKey_ptr, CRYSRSAPrivKey_t *PrivKey_ptr, CRYS_RSAKGData_t *KeyGenData_ptr ) { /* LOCAL DECLARATIONS */ /* error identification */ CRYSError_t Error; /* the P,Q primitive pointers */ DxUint32_t *P_ptr,*Q_ptr; DxUint32_t Success, maxCountRegs, regSizeWords; /* the virtual address - localy defined just for code clearnce */ DxUint32_t VirtualHwBaseAddr = 0; /* FUNCTION LOGIC */ /* check that key size is not great, than allowed for Key Generation because pKA memory limit */ if( PubKey_ptr->nSizeInBits > LLF_PKI_PKA_MAX_KEY_GENERATION_SIZE_BITS ) return LLF_PKI_KG_UNSUPPORTED_KEY_SIZE; /* ............... initialize local variables ......................... */ /* -------------------------------------------------------------------- */ /* initialize the error identifier to the CRYS_OK ( success ) */ Error = CRYS_OK; /* for avoid compailer warning */ Success = 0; /* ............... getting the hardware semaphore ..................... */ /* -------------------------------------------------------------------- */ Error = DX_VOS_SemWait( SemPkaId , DX_INFINITE ); if(Error) goto Return; /* ............... mapping the physical memory to the virtual one ...... */ /* --------------------------------------------------------------------- */ Error = DX_VOS_MemMap( PLAT_CryptoCellBaseAddr, /* low address - in */ LLF_PKI_HW_CRYPTO_ADDR_SPACE, /* 16 LS bit space - in */ &VirtualHwBaseAddr ); /* The virtual address - out */ if(Error) goto End_OnlySemRelease; /* ................... initialize the PKA .............................*/ /* maximal count of allocated registers */ regSizeWords = (LLF_PKI_PKA_MAX_KEY_GENERATION_SIZE_BITS/32)/2 + 1; /* maximal count registers */ maxCountRegs = LLF_PKI_PKA_MAX_REGS_MEM_SIZE_BYTES / ((LLF_PKI_PKA_MAX_KEY_GENERATION_SIZE_BITS/8)/2 + 4); maxCountRegs = maxCountRegs > LLF_PKI_PKA_MAX_COUNT_OF_PHYS_MEM_REGS ? LLF_PKI_PKA_MAX_COUNT_OF_PHYS_MEM_REGS : maxCountRegs; Error = LLF_PKI_PKA_DefaultInitPKA( PubKey_ptr->nSizeInBits/2, regSizeWords, VirtualHwBaseAddr ); if( Error != CRYS_OK ) goto End; /* initialize the P,Q pointers to the buffers on the keygen data structure */ P_ptr = KeyGenData_ptr->KGData.p; Q_ptr = KeyGenData_ptr->KGData.q; /* ............... calling the Non CRT or CRT KeyGen functions ......... */ /* --------------------------------------------------------------------- */ if( PrivKey_ptr->OperationMode == CRYS_RSA_NoCrt ) { do { Error = LLF_PKI_genKeyNonCrt( PubKey_ptr->e, PubKey_ptr->eSizeInBits, PubKey_ptr->nSizeInBits, 0, /*testsCount should be set automatically*/ &Success, P_ptr, Q_ptr, PubKey_ptr->n, PrivKey_ptr->PriveKeyDb.NonCrt.d, ((LLF_pki_key_gen_db_t *)(KeyGenData_ptr->KGData.crysRSAKGDataIntBuff))->temp, VirtualHwBaseAddr ); if( Error != CRYS_OK ) goto End; #if !defined RSA_KG_NO_RND if( !Success ) { Error = CRYS_RSA_GenerateVectorInRangeX931( PubKey_ptr->nSizeInBits/(2*32), P_ptr); if( Error != CRYS_OK ) goto End; Error = CRYS_RSA_GenerateVectorInRangeX931( PubKey_ptr->nSizeInBits/(2*32), Q_ptr); if( Error != CRYS_OK ) goto End; } #endif }while(!Success); /* set the key source as external - a PATCH since 'D' is not decrypted in SK2 */ PrivKey_ptr->KeySource = CRYS_RSA_ExternalKey; /* set the length of d in bits */ PrivKey_ptr->PriveKeyDb.NonCrt.dSizeInBits = \ CRYS_COMMON_GetWordsCounterEffectiveSizeInBits( PrivKey_ptr->PriveKeyDb.NonCrt.d, (DxUint16_t)(PubKey_ptr->nSizeInBits+31)/32); }/* end of non CRT case */ else { /* CRT case */ do { Error = LLF_PKI_genKeyCrt( PubKey_ptr->e , PubKey_ptr->eSizeInBits, PubKey_ptr->nSizeInBits, 0, /*testsCount should be set automatically*/ &Success, P_ptr, Q_ptr, PubKey_ptr->n , PrivKey_ptr->PriveKeyDb.Crt.dP, PrivKey_ptr->PriveKeyDb.Crt.dQ, PrivKey_ptr->PriveKeyDb.Crt.qInv, ((LLF_pki_key_gen_db_t *)(KeyGenData_ptr->KGData.crysRSAKGDataIntBuff))->temp, VirtualHwBaseAddr); if( Error != CRYS_OK ) goto End; #if !defined RSA_KG_NO_RND if( !Success ) { Error = CRYS_RSA_GenerateVectorInRangeX931(PubKey_ptr->nSizeInBits/(2*32), P_ptr); if( Error != CRYS_OK ) goto End; Error = CRYS_RSA_GenerateVectorInRangeX931(PubKey_ptr->nSizeInBits/(2*32), Q_ptr); if( Error != CRYS_OK ) goto End; } #endif }while( !Success ); /* Load P,Q vectors */ DX_VOS_FastMemCpy(PrivKey_ptr->PriveKeyDb.Crt.P , P_ptr , PubKey_ptr->nSizeInBits / 16); DX_VOS_FastMemCpy(PrivKey_ptr->PriveKeyDb.Crt.Q , Q_ptr , PubKey_ptr->nSizeInBits / 16); }/* end of CRT case */ /* load 'n' to the private */ DX_VOS_FastMemCpy(PrivKey_ptr->n , PubKey_ptr->n , PubKey_ptr->nSizeInBits / 8); End: /* clear secure sensitive data from allocated registers, including rT0,rT1 */ LLF_PKI_PKA_ClearBlockOfRegs(0/*first*/, maxCountRegs - 2/*CountOfRegs*/, LenIDn+1, VirtualHwBaseAddr); LLF_PKI_PKA_ClearBlockOfRegs(30/*first*/, 2/*CountOfRegs*/, LenIDn+1, VirtualHwBaseAddr); /* end of PKA operations */ LLF_PKI_PKA_FinishPKA( VirtualHwBaseAddr ); /* .... un mappping the physical memory and releasing the semaphore ...... */ /*-------------------------------------------------------------------------*/ DX_VOS_MemUnMap( &VirtualHwBaseAddr, /* virtual address - in */ LLF_PKI_HW_CRYPTO_ADDR_SPACE ); /* 16 LS bit space - in */ End_OnlySemRelease: /* release the hardware semaphore */ DX_VOS_SemGive ( SemPkaId ); Return: return Error; }/* END OF CC_LLF_PKI_RSA_GenerateKeyPair */
/** * @brief CRYS_KDF_KeyDerivFunc performs key derivation according to one of some modes defined in standards: ANSI X9.42-2001, ANSI X9.63, OMA_TS_DRM_DRM_V2_0-20050712-C, ISO/IEC 18033-2. The present implementation of the function allows the following operation modes: - CRYS_KDF_ASN1_DerivMode - mode based on ASN.1 DER encoding; - CRYS_KDF_ConcatDerivMode - mode based on concatenation; - CRYS_KDF_X963_DerivMode = CRYS_KDF_ConcatDerivMode; - CRYS_KDF_OMA_DRM_DerivMode - specific mode for OMA DRM; - CRYS_KDF_ISO18033_KDF1_DerivMode - specific mode according to ECIES-KEM algorithm (ISO/IEC 18033-2). The purpose of this function is to derive a keying data from the shared secret value and some other optional shared information (SharedInfo). For calling the API on some specific modes may be used the following macros: - CRYS_KDF_ASN1_KeyDerivFunc ; - CRYS_KDF_ConcatKeyDerivFunc ; - CRYS_KDF_OMADRM_DerivFunc. \note The length in Bytes of the hash result buffer is denoted by "hashlen". \note All buffers arguments are represented in Big-Endian format. @param[in] ZZSecret_ptr - A pointer to shared secret value octet string. @param[in] ZZSecretSize - The size of the shared secret value in bytes. The maximal size is defined as: CRYS_KDF_MAX_SIZE_OF_SHARED_SECRET_VALUE. @param[in] OtherInfo - The pointer to structure , containing the data, shared by two entities of agreement and the data sizes. This argument is optional for some modes (if it is not needed - set NULL). On KDF OMA_DRM and two ISO/IEC 18033-2 modes - set NULL. On KDF ASN1 mode the OtherInfo and its AlgorithmID entry are mandatory. @param[in] KDFhashMode - The KDF identifier of hash function to be used. The hash function output must be at least 160 bits. @param[in] derivation_mode - Specifies one of above described derivation modes. @param[out] KeyingData_ptr - A pointer to the buffer for derived keying data. @param[in] KeyingDataSizeBytes - The size in bytes of the keying data to be derived. The maximal size is defined as: CRYS_KDF_MAX_SIZE_OF_KEYING_DATA. @return CRYSError_t - On success the value CRYS_OK is returned, and on failure an ERROR as defined in CRYS_KDF_error.h: CRYS_KDF_INVALID_ARGUMENT_POINTER_ERROR CRYS_KDF_INVALID_KEY_DERIVATION_MODE_ERROR CRYS_KDF_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR CRYS_KDF_INVALID_SIZE_OF_DATA_TO_HASHING_ERROR CRYS_KDF_INVALID_ARGUMENT_HASH_MODE_ERROR CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR CRYS_KDF_INVALID_KEYING_DATA_SIZE_ERROR */ CEXPORT_C CRYSError_t CRYS_KDF_KeyDerivFunc( DxUint8_t *ZZSecret_ptr, DxUint32_t ZZSecretSize, CRYS_KDF_OtherInfo_t *OtherInfo_ptr, CRYS_KDF_HASH_OpMode_t KDFhashMode, CRYS_KDF_DerivFuncMode_t derivation_mode, DxUint8_t *KeyingData_ptr, DxUint32_t KeyingDataSizeBytes ) { /* FUNCTION DECLARATIONS */ /* The return error identifier */ CRYSError_t Error; /* HASH function context structure buffer and parameters */ CRYS_HASHUserContext_t HashContext; CRYS_HASH_OperationMode_t hashMode; DxUint32_t HashOutputSizeBytes; /*The result buffer for the Hash*/ CRYS_HASH_Result_t HashResultBuff; /* Total count of full HASH blockss for deriving the keying data */ DxUint32_t CountOfHashBlocks; /* Loop counters */ DxUint32_t i, j; /*counter of Hash blocks (to be hashed with ZZ and OtherInfo) */ DxUint32_t Counter; /* Current output buffer position */ DxUint32_t CurrentOutputBuffPos = 0; DxUint32_t *OtherInfoEntry_ptr; DxUint8_t *temp_ptr; DxUint32_t remBuffSize; /*.... HASH Init function .....*/ /* FUNCTION LOGIC */ /* ............... local initializations .............................. */ /* -------------------------------------------------------------------- */ /* initializing the Error to O.K */ Error = CRYS_OK; /* ............... if not supported exit .............................. */ /* -------------------------------------------------------------------- */ PRINT_INFO("--->NOW inter into CRYS_KDF_KeyDerivFunc\n"); RETURN_IF_KDF_UNSUPPORTED( ZZSecret_ptr , ZZSecretSize , OtherInfo_ptr , KDFhashMode , derivation_mode , KeyingData_ptr , KeyingDataSizeBytes , hashMode , HashOutputSizeBytes , HashContext.valid_tag , CountOfHashBlocks , i , j , Counter , CurrentOutputBuffPos , HashResultBuff[0] , OtherInfoEntry_ptr , temp_ptr , remBuffSize , Error , Error ); #ifndef CRYS_NO_HASH_SUPPORT #ifndef CRYS_NO_KDF_SUPPORT /* ............... checking the parameters validity ................... */ /* -------------------------------------------------------------------- */ /* if an argument pointer is DX_NULL return an error */ if( ZZSecret_ptr == DX_NULL || KeyingData_ptr == DX_NULL ) return CRYS_KDF_INVALID_ARGUMENT_POINTER_ERROR; if( derivation_mode >= CRYS_KDF_DerivFunc_NumOfModes ) return CRYS_KDF_INVALID_KEY_DERIVATION_MODE_ERROR; if( derivation_mode == CRYS_KDF_ASN1_DerivMode && (OtherInfo_ptr == DX_NULL || OtherInfo_ptr->SizeOfAlgorithmID == 0)) return CRYS_KDF_INVALID_ARGUMENT_POINTER_ERROR; /*On KDF1 and KDF2 derivation modes set OtherInfo_ptr = DX_NULL */ if(derivation_mode == CRYS_KDF_ISO18033_KDF1_DerivMode || derivation_mode == CRYS_KDF_ISO18033_KDF2_DerivMode){ OtherInfo_ptr = DX_NULL; } /* Check sizes of the input data to be hashed according to KDF * * limitations) */ if(ZZSecretSize == 0 || ZZSecretSize > CRYS_KDF_MAX_SIZE_OF_SHARED_SECRET_VALUE ) return CRYS_KDF_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR; if( OtherInfo_ptr != DX_NULL ) { if( OtherInfo_ptr->SizeOfAlgorithmID > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY ) return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR; if( OtherInfo_ptr->SizeOfPartyUInfo > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY ) return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR; if( OtherInfo_ptr->SizeOfPartyVInfo > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY ) return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR; if( OtherInfo_ptr->SizeOfSuppPrivInfo > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY ) return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR; if( OtherInfo_ptr->SizeOfSuppPubInfo > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY ) return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR; } /* Check the size of keying data */ if( KeyingDataSizeBytes == 0 || KeyingDataSizeBytes > CRYS_KDF_MAX_SIZE_OF_KEYING_DATA) return CRYS_KDF_INVALID_KEYING_DATA_SIZE_ERROR; /*................ Setting parameters according to current operation modes .......... */ /*------------------------------------------------------------------------------------*/ switch( KDFhashMode ) { case CRYS_KDF_HASH_SHA1_mode: hashMode = CRYS_HASH_SHA1_mode; HashOutputSizeBytes = CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES; break; case CRYS_KDF_HASH_SHA224_mode: hashMode = CRYS_HASH_SHA224_mode; HashOutputSizeBytes = CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES; break; case CRYS_KDF_HASH_SHA256_mode: hashMode = CRYS_HASH_SHA256_mode; HashOutputSizeBytes = CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES; break; case CRYS_KDF_HASH_SHA384_mode: hashMode = CRYS_HASH_SHA384_mode; HashOutputSizeBytes = CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES; break; case CRYS_KDF_HASH_SHA512_mode: hashMode = CRYS_HASH_SHA512_mode; HashOutputSizeBytes = CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES; break; default: return CRYS_KDF_INVALID_ARGUMENT_HASH_MODE_ERROR; } /* Count of HASH blocks needed for key derivation etc. */ CountOfHashBlocks = ( KeyingDataSizeBytes + HashOutputSizeBytes - 1 )/ HashOutputSizeBytes; temp_ptr = (DxUint8_t*)&gKdfHashTempBuff[0]; remBuffSize = CRYS_HASH_BLOCK_SIZE_IN_BYTES; /* ********** Keying data derivation loop ************ */ for( i = 0; i < CountOfHashBlocks; i++ ) { /*.... HASH Init function .....*/ Error = CRYS_HASH_Init(&HashContext, hashMode); PRINT_INFO("--->NOW after CRYS_HASH_Init\n"); if(Error != CRYS_OK) return Error; /*....... Hashing input data by calling HASH_Update function .......*/ /*------------------------------------------------------------------*/ /*.... Hashing of the shared secret value ....*/ Error = _DX_KDF_HASH_UnalignUpdate(&HashContext, ZZSecret_ptr,ZZSecretSize, temp_ptr, &remBuffSize); PRINT_INFO("--->NOW after _DX_KDF_HASH_UnalignUpdate\n"); if(Error != CRYS_OK) goto End; /*.... Hashing of the AlgorithmID (on ASN1 Derivation Mode only) ....*/ if( derivation_mode == CRYS_KDF_ASN1_DerivMode ) { Error = _DX_KDF_HASH_UnalignUpdate(&HashContext, (DxUint8_t *)(OtherInfo_ptr->AlgorithmID), OtherInfo_ptr->SizeOfAlgorithmID, temp_ptr, &remBuffSize); PRINT_INFO("--->NOW after derivation_mode == CRYS_KDF_ASN1_DerivMode , _DX_KDF_HASH_UnalignUpdate\n"); if(Error != CRYS_OK) goto End; } /* Set the blocks counter in big endianness mode */ if(derivation_mode == CRYS_KDF_ISO18033_KDF1_DerivMode) Counter = CRYS_COMMON_REVERSE32(i); else Counter = CRYS_COMMON_REVERSE32(i+1); PRINT_INFO("--->NOW after CRYS_COMMON_REVERSE32()\n"); /*.... Hashing of the blocks counter ....*/ Error = _DX_KDF_HASH_UnalignUpdate(&HashContext, (DxUint8_t *)&Counter, sizeof(DxUint32_t), temp_ptr, &remBuffSize); if(Error != CRYS_OK) goto End; /* ..... Hashing of remaining data of the OtherInfo ..... */ if( OtherInfo_ptr != DX_NULL ) { /* Set OtherInfoEntry_ptr to second entry pointer */ OtherInfoEntry_ptr = (DxUint32_t*)OtherInfo_ptr + CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY/4 + 1; /* OtherInfo data concatenating and hashing loop */ for( j = 0; j < CRYS_KDF_COUNT_OF_OTHER_INFO_ENTRIES - 1; j++ ) { /* if entry exists hash it */ if( *(OtherInfoEntry_ptr + CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY/4) != 0 ) { Error = _DX_KDF_HASH_UnalignUpdate(&HashContext, (DxUint8_t *)OtherInfoEntry_ptr/*pointer to entry*/, *(OtherInfoEntry_ptr + CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY/4)/*size of entry*/, temp_ptr, &remBuffSize); if(Error != CRYS_OK) goto End; } /* Shift the pointer to the next entry */ OtherInfoEntry_ptr += CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY/4 + 1; } } /* last Hash update on remaining data in the temp buffer */ if(remBuffSize < CRYS_HASH_BLOCK_SIZE_IN_BYTES) { Error = CRYS_HASH_Update(&HashContext, temp_ptr, CRYS_HASH_BLOCK_SIZE_IN_BYTES - remBuffSize); PRINT_INFO("--->NOW after CRYS_HASH_Update()\n"); if(Error != CRYS_OK) goto End; } /* .......... HASH Finish operation ............. */ Error = CRYS_HASH_Finish( &HashContext , HashResultBuff ); PRINT_INFO("--->NOW after CRYS_HASH_Finish()\n"); if(Error != CRYS_OK) goto End; /* Correction of output data size for last block ( if it is not full ) */ if( i == CountOfHashBlocks - 1 ) HashOutputSizeBytes = KeyingDataSizeBytes - i * HashOutputSizeBytes; PRINT_INFO("--->NOW begin DX_VOS_FastMemCpy\n"); /* Copying HASH data into output buffer */ DX_VOS_FastMemCpy(&KeyingData_ptr[CurrentOutputBuffPos],(DxUint8_t *)HashResultBuff, HashOutputSizeBytes); /* Increment the output buffer position */ CurrentOutputBuffPos += HashOutputSizeBytes; } End: DX_VOS_MemSetZero(gKdfHashTempBuff, sizeof(gKdfHashTempBuff)); return Error; #endif /*CRYS_NO_KDF_SUPPORT*/ #endif /*CRYS_NO_HASH_SUPPORT*/ }/* END OF CRYS_KDF_KeyDerivationFunc */
CEXPORT_C CRYSError_t _DX_RSA_VerifyInit(CRYS_RSAPubUserContext_t *UserContext_ptr, CRYS_RSAUserPubKey_t *UserPubKey_ptr, CRYS_RSA_HASH_OpMode_t hashFunc, CRYS_PKCS1_MGF_t MGF, DxUint16_t SaltLen, CRYS_PKCS1_version PKCS1_ver) { /* FUNCTION DECLERATIONS */ /* The return error identifier */ CRYSError_t Error; /* This pointer is allocated in order to remove compiler alias problems */ void *tempWorkingctx_ptr; /* defining a pointer to the active context allcated by the CCM */ RSAPubContext_t *ccmWorkingContext_ptr ; /*Pointer to the public key for lengths checking*/ CRYSRSAPubKey_t *PubKey_ptr; /*The size of the modulus for lengths checking*/ DxUint16_t ModulusSizeBytes; /* FUNCTION LOGIC */ /* ............... local initializations .............................. */ /* -------------------------------------------------------------------- */ /* initializing the Error to O.K */ Error = CRYS_OK; /* initialize the module size to cancel compilers warnings */ ModulusSizeBytes = 0; /* ............... if not supported exit .............................. */ /* -------------------------------------------------------------------- */ RETURN_IF_RSA_UNSUPPORTED(UserContext_ptr , UserPubKey_ptr , hashFunc , MGF , SaltLen , PKCS1_ver, ccmWorkingContext_ptr , PubKey_ptr , ModulusSizeBytes , Error , Error , Error , Error , Error , Error , Error , Error , Error , Error , Error , Error , Error); #ifndef CRYS_NO_HASH_SUPPORT #ifndef CRYS_NO_PKI_SUPPORT /* ............... checking the parameters validity ................... */ /* -------------------------------------------------------------------- */ /* if the users context ID pointer is DX_NULL return an error */ if( UserContext_ptr == DX_NULL ) return CRYS_RSA_INVALID_USER_CONTEXT_POINTER_ERROR; /*if the private key object is DX_NULL return an error*/ if (UserPubKey_ptr == DX_NULL) return CRYS_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR; /* check if the hash operation mode is legal */ if( hashFunc >= CRYS_RSA_HASH_NumOfModes) return CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR; /* check if the MGF operation mode is legal */ if(MGF >= CRYS_RSA_NumOfMGFFunctions) return CRYS_RSA_MGF_ILLEGAL_ARG_ERROR; /* check that the PKCS1 version argument is legal*/ if(PKCS1_ver >= CRYS_RSA_NumOf_PKCS1_versions) return CRYS_RSA_PKCS1_VER_ARG_ERROR; /*According to the PKCS1 ver 2.1 standart it is not recommended to use MD5 hash therefore we do not support it */ if(PKCS1_ver == CRYS_PKCS1_VER21 && hashFunc == CRYS_RSA_HASH_MD5_mode) return CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR; #ifndef DX_OEM_FW if (DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserContext_ptr, sizeof(CRYS_RSAPubUserContext_t)) || DxCcAcl_IsBuffAccessOk(ACCESS_READ, UserPubKey_ptr, sizeof(CRYS_RSAUserPubKey_t))){ return CRYS_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR; } #endif /*If the validation tag is incorrect*/ if(UserPubKey_ptr->valid_tag != CRYS_RSA_PUB_KEY_VALIDATION_TAG) return CRYS_RSA_PUB_KEY_VALIDATION_TAG_ERROR; /*Checking if a check on salt length is needed*/ if(SaltLen != CRYS_RSA_VERIFY_SALT_LENGTH_UNKNOWN && PKCS1_ver == CRYS_PKCS1_VER21) { /*Initializing the Modulus Size in Bytes needed for SaltLength parameter check*/ PubKey_ptr = (CRYSRSAPubKey_t *)UserPubKey_ptr->PublicKeyDbBuff; /*Note: the (-1) is due to the PKCS#1 Ver2.1 standard section 9.1.1*/ ModulusSizeBytes = (DxUint16_t)((PubKey_ptr->nSizeInBits -1) / 8); if((PubKey_ptr->nSizeInBits -1) % 8) ModulusSizeBytes++; } /* .................. initializing local variables ................... */ /* ------------------------------------------------------------------- */ /* ................. aquiring the RSA context ............................. */ /* ----------------------------------------------------------------------- */ /*Get the working context*/ Error = CRYS_CCM_GetContext( UserContext_ptr, /* the users context space - in */ &tempWorkingctx_ptr, /* the CCM context returned - out */ DX_RSA_VERIFY_CONTEXT, /* AES type - in */ AES_DONT_DECRYPT_CONTEXT); /* need to decrypt context in AES_block*/ if(Error != CRYS_OK ) return Error; ccmWorkingContext_ptr = (RSAPubContext_t*)tempWorkingctx_ptr; /*Reset the Context handler for improper previous values initialized*/ DX_VOS_MemSet(ccmWorkingContext_ptr,0,sizeof(RSAPubContext_t)); /* ................. loading the context .................................. */ /* ------------------------------------------------------------------------ */ /*Initializing the Hash operation mode in the RSA Context level*/ ccmWorkingContext_ptr->HashOperationMode = hashFunc; switch(ccmWorkingContext_ptr->HashOperationMode) { case CRYS_RSA_HASH_MD5_mode : ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_MD5_DIGEST_SIZE_IN_WORDS; Error = CRYS_HASH_Init( ((CRYS_HASHUserContext_t *)((ccmWorkingContext_ptr->CRYSPKAHashCtxBuff))), CRYS_HASH_MD5_mode); /*The MD5 mode according to the Hash level enum*/ if(Error != CRYS_OK) goto END_WITH_ERROR; break; case CRYS_RSA_HASH_SHA1_mode: ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA1_DIGEST_SIZE_IN_WORDS; Error = CRYS_HASH_Init( ((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)) , CRYS_HASH_SHA1_mode); /*The SHA1 mode according to the Hash level enum*/ if(Error != CRYS_OK) goto END_WITH_ERROR; break; case CRYS_RSA_HASH_SHA224_mode: ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA224_DIGEST_SIZE_IN_WORDS; Error = CRYS_HASH_Init( ((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)), CRYS_HASH_SHA224_mode); /*The SHA224 mode according to the Hash level enum*/ if(Error != CRYS_OK) goto END_WITH_ERROR; break; case CRYS_RSA_HASH_SHA256_mode: ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA256_DIGEST_SIZE_IN_WORDS; Error = CRYS_HASH_Init( ((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)), CRYS_HASH_SHA256_mode); /*The SHA256 mode according to the Hash level enum*/ if(Error != CRYS_OK) goto END_WITH_ERROR; break; case CRYS_RSA_HASH_SHA384_mode: ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA384_DIGEST_SIZE_IN_WORDS; Error = CRYS_HASH_Init(((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)), CRYS_HASH_SHA384_mode); /*The SHA384 mode according to the Hash level enum*/ if(Error != CRYS_OK) goto END_WITH_ERROR; break; case CRYS_RSA_HASH_SHA512_mode: ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA512_DIGEST_SIZE_IN_WORDS; Error = CRYS_HASH_Init(((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)), CRYS_HASH_SHA512_mode); /*The SHA512 mode according to the Hash level enum*/ if(Error != CRYS_OK) goto END_WITH_ERROR; break; case CRYS_RSA_After_MD5_mode: /*For PKCS1 v1.5 when the data in is already hashed with MD5*/ ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_MD5_DIGEST_SIZE_IN_WORDS; break; case CRYS_RSA_After_SHA1_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA1*/ ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA1_DIGEST_SIZE_IN_WORDS; break; case CRYS_RSA_After_SHA224_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA224*/ ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA224_DIGEST_SIZE_IN_WORDS; break; case CRYS_RSA_After_SHA256_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA256*/ ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA256_DIGEST_SIZE_IN_WORDS; break; case CRYS_RSA_After_SHA384_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA384*/ ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA384_DIGEST_SIZE_IN_WORDS; break; case CRYS_RSA_After_SHA512_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA512*/ ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA512_DIGEST_SIZE_IN_WORDS; break; case CRYS_RSA_HASH_NO_HASH_mode: /*Used for PKCS1 v1.5 Encrypt and Decrypt - not relevant in Sign-Verify*/ break; /*do nothing*/ case CRYS_RSA_After_HASH_NOT_KNOWN_mode : /*used for PKCS1 v1.5 Verify only - possible to derive the hash mode from the signature*/ if( PKCS1_ver == CRYS_PKCS1_VER21) { Error = CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR; goto END_WITH_ERROR; } break; /*do nothing*/ default: Error = CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR; goto END_WITH_ERROR; } switch(PKCS1_ver) { case CRYS_PKCS1_VER15: ccmWorkingContext_ptr->PKCS1_Version=CRYS_PKCS1_VER15; break; case CRYS_PKCS1_VER21: ccmWorkingContext_ptr->PKCS1_Version=CRYS_PKCS1_VER21; /*Checking restriction of Salt Length ; Hash output size and the mosulus*/ if(SaltLen != CRYS_RSA_VERIFY_SALT_LENGTH_UNKNOWN && ModulusSizeBytes < (DxUint32_t)(ccmWorkingContext_ptr->HASH_Result_Size*4 + SaltLen + 2)) { Error = CRYS_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR; goto END_WITH_ERROR; } break; default: Error = CRYS_RSA_PKCS1_VER_ARG_ERROR; goto END_WITH_ERROR; } switch(MGF) { case CRYS_PKCS1_MGF1: case CRYS_PKCS1_NO_MGF: ccmWorkingContext_ptr->MGF_2use = MGF; break; default: Error = CRYS_RSA_MGF_ILLEGAL_ARG_ERROR; goto END_WITH_ERROR; } /*Copying the RSA Pub key argument to the context*/ DX_VOS_FastMemCpy((DxUint8_t *)&ccmWorkingContext_ptr->PubUserKey,(DxUint8_t *)UserPubKey_ptr,sizeof(CRYS_RSAUserPubKey_t)); /*Initial the Salt random length relevant for PKCS#1 Ver2.1*/ ccmWorkingContext_ptr->SaltLen = SaltLen; /* Initialize the size of the modulus */ ccmWorkingContext_ptr->nSizeInBytes = (((CRYSRSAPubKey_t*)UserPubKey_ptr->PublicKeyDbBuff)->nSizeInBits+7)/8; /* set the RSA tag to the users context */ UserContext_ptr->valid_tag = CRYS_RSA_VERIFY_CONTEXT_VALIDATION_TAG; goto END; END: /* ................. release the context ................................. */ /* ----------------------------------------------------------------------- */ Error = CRYS_CCM_ReleaseContext(UserContext_ptr, /* the users context space - in */ ccmWorkingContext_ptr, /* the CCM context returned - in */ DX_RSA_VERIFY_CONTEXT); /* RSA type - in */ return Error; END_WITH_ERROR: /* ................. release the context ................................. */ /* ----------------------------------------------------------------------- */ { CRYSError_t Error1 = CRYS_CCM_ReleaseContext(UserContext_ptr, /* the users context space - in */ ccmWorkingContext_ptr, /* the CCM context returned - in */ DX_RSA_VERIFY_CONTEXT); /* RSA type - in */ if(Error1 != CRYS_OK) { PLAT_LOG_DEV_PRINT(( 10 ," \n Error1 from CRYS_CCM_ReleaseContext is %lX \n" ,Error1)); } } /* .............. clearing the users context in case of error.......... */ /* -------------------------------------------------------------------- */ DX_VOS_MemSet(UserContext_ptr,0,sizeof(CRYS_RSAPubUserContext_t)); return Error; #endif /* !CRYS_NO_HASH_SUPPORT */ #endif /* !CRYS_NO_PKI_SUPPORT */ }/* END OF _DX_RSA_VerifyInit */
/** Function Name: CRYS_RSA_PKCS1_v1_5_Decode Date: 18-01-2005 Author: Ohad Shperling \brief CRYS_RSA_PKCS1_v1_5_Encode implements EME-PKCS1_v1_5_Encoding algorithm as defined in PKCS#1 v1.5 Sec 8.1 @param[in] EncryptedBlock - Pointer to the Encrypted block to parse - given after an exponent operation @param[in] K - The modulus size denoted in octets. @param[out] D_ptr - Pointer to the output Data - to parse out of the EncryptedBlock buffer @param[out] DSize - Denotes the Data size Note BlockType - BlockType for PUB Key is 02 BlockType for Priv Key is 01 @return CRYSError_t - CRYS_OK, */ CRYSError_t CRYS_RSA_PKCS1_v1_5_Decode(DxUint8_t *EncryptedBlock, DxUint16_t K, DxUint8_t *D_ptr, DxUint16_t *DSize_ptr) { /* The return error identifier */ CRYSError_t Error; /* Padding String Size */ DxUint16_t I = 0; /*The block Type parsed from the input*/ CRYS_PKCS1_Block_Type BlockType; DxUint8_t Mask=0x00; /* FUNCTION LOGIC */ /* .................. initializing local variables ................... */ /* ------------------------------------------------------------------- */ /* initializing the Error to O.K */ Error = CRYS_OK; /*-------------------------------------------*/ /* */ /* Step 4 : Decrypted block parsing */ /* */ /* 00 || BT || PS || 00 || D */ /* */ /* MSB LSB */ /* |<----- Size = K ------->| */ /* */ /* */ /*-------------------------------------------*/ if(EncryptedBlock[0] != 0) return CRYS_RSA_15_ERROR_IN_DECRYPTED_BLOCK_PARSING; BlockType = (CRYS_PKCS1_Block_Type)EncryptedBlock[1]; switch(BlockType) { case CRYS_RSA_PKCS1_15_MODE00: /*Mask=0x00;*/ /* Please refer to PKCS1 Ver 1.5 Standart for the security argument why not to use this kind of Block Type */ return CRYS_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED ; case CRYS_RSA_PKCS1_15_MODE01: Mask=0xFF; break; case CRYS_RSA_PKCS1_15_MODE02: Mask=Mask; /* junk - was created using Random */ break; default: return CRYS_RSA_15_ERROR_IN_DECRYPTED_BLOCK_PARSING; } /* scan and check the padding string for CRYS_RSA_PKCS1_15_MODE01 */ if(BlockType==CRYS_RSA_PKCS1_15_MODE01) { for(I=2;I<K;I++) { if(EncryptedBlock[I]!=Mask) /* start scanning from cell 3 */ break; } /* check that the current octet (next after after PS) is 0x00 */ if( EncryptedBlock[I] != 0 ) return CRYS_RSA_15_ERROR_IN_DECRYPTED_DATA; } /* scan the padding string for CRYS_RSA_PKCS1_15_MODE02 */ if(BlockType==CRYS_RSA_PKCS1_15_MODE02) { for(I=2;I<K;I++) { if(EncryptedBlock[I] == 0x00) break; } } /* check that PS size is not less than 8; note: at this point I is equal to PS size + 2 */ if( I - 2 < 8 ) return CRYS_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE; /*Checking that the Output buffer Size is enough large for result output */ if( *DSize_ptr < (DxUint16_t)(K-(I+1)) ) { *DSize_ptr = (DxUint16_t)(K-(I+1)); return CRYS_RSA_DECRYPT_INVALID_OUTPUT_SIZE; } else if( *DSize_ptr > (DxUint16_t)(K-(I+1))) /* set actual size of decrypted message */ *DSize_ptr = (DxUint16_t)(K-(I+1)); /* copy decrypted message into output */ /*note - if I+1 == K than the decrypted data size is zero*/ DX_VOS_FastMemCpy( D_ptr, &EncryptedBlock[I+1], *DSize_ptr ); return Error; }
CRYSError_t CRYS_RSA_BER_BerParser(DxUint8_t *Data_ptr, DxUint16_t DataSize, BerParserObj_t *BerParserObj_ptr) { /*** Variables definitions and initializations ***/ static const DxUint8_t AlgorithmID_MD5[] ={0x2A,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04}; static const DxUint8_t AlgorithmID_MD5_V2[] ={0x2A,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05}; static const DxUint8_t AlgorithmID_SHA[] ={0x2b,0x0e,0x03,0x02,0x1a}; static const DxUint8_t AlgorithmID_SHA224[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04}; static const DxUint8_t AlgorithmID_SHA256[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01}; static const DxUint8_t AlgorithmID_SHA384[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02}; static const DxUint8_t AlgorithmID_SHA512[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03}; /* Temporary variable for size*/ DxUint16_t TempLength=0; /* Calculated size of passed data and size of Message Digest (HASH) */ DxUint16_t CalcSize = 0, MDSize = 0; /* Certificate pointer */ DxUint8_t* Cert_ptr = Data_ptr; /* to avoid compilers warnings */ DataSize = DataSize; /***** FUNCTION LOGIC ****/ /* skip on the DigestInfo sequence tag */ Cert_ptr++; /* skip on SEQUENCE tag */ CRT_API_GetLengthField(&Cert_ptr, &TempLength); /* skip on the AlgorithmIdentifier sequence tag */ Cert_ptr++; /* skip on SEQUENCE tag */ CRT_API_GetLengthField(&Cert_ptr, &TempLength); /* skip on the OBJECT IDENTIFIER length field */ if(*Cert_ptr++ != ASN1_OBJECT_IDENTIFIER)/* skip on OBJECT IDENTIFIER tag */ return (CRYS_RSA_ERROR_BER_PARSING); CRT_API_GetLengthField(&Cert_ptr, &TempLength); if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_MD5,TempLength)) /* md5 hash algorithm */ { BerParserObj_ptr->DigestAlg = CRYS_HASH_MD5_mode; MDSize = CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES; } else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_MD5_V2,TempLength)) /* md5_v2 hash algorithm */ { BerParserObj_ptr->DigestAlg =CRYS_HASH_MD5_mode; MDSize = CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES; } else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA,TempLength)) /* sha1 hash algorithm */ { BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA1_mode; MDSize = CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES; } else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA224,TempLength)) /* sha224 hash algorithm */ { BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA224_mode; MDSize = CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES; } else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA256,TempLength)) /* sha256 hash algorithm */ { BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA256_mode; MDSize = CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES; } else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA384,TempLength)) /* sha384 hash algorithm */ { BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA384_mode; MDSize = CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES; } else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA512,TempLength)) /* sha512 hash algorithm */ { BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA512_mode; MDSize = CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES; } else return (CRYS_RSA_ERROR_BER_PARSING);/* unknown algorithm */ /* move the Cert_ptr to next position */ Cert_ptr += TempLength; /* skip on the DX_NULL tag */ if(*Cert_ptr ++ != ASN1_NULL)/* skip on DX_NULL tag */ return (CRYS_RSA_ERROR_BER_PARSING); CRT_API_GetLengthField(&Cert_ptr, &TempLength); /* skip on the BIT STRING length field + 0 (unused) byte */ if(*Cert_ptr ++ != ASN1_OCTET_STRING) /* skip on BIT STRING tag */ return (CRYS_RSA_ERROR_BER_PARSING); CRT_API_GetLengthField(&Cert_ptr, &TempLength); /* Countermeasure against CVE-2006-4339 (candidate) when using an RSA key with exponent 3, which allows remote attackers to forge a PKCS #1 v1.5 signature that is signed by the RSA */ /* Calculate data size = the actual size we progress untill now (should be equal to the ASN.1 size) + HASH size in bytes */ CalcSize = (DxUint16_t)(Cert_ptr - Data_ptr) + MDSize; /* if there is more data (passed garbage), than return an error */ if (DataSize > CalcSize) return CRYS_RSA_ERROR_BER_PARSING; /* Write a Message digest from the certificate to the output parameter */ /* BerParserObj_ptr->MessageDigest_ptr = Cert_ptr; */ switch(BerParserObj_ptr->DigestAlg) { case CRYS_HASH_MD5_mode: PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES)); /* MD5 size */ DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES)); break; case CRYS_HASH_SHA1_mode: PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES)); /* SHA1 size */ DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES)); break; case CRYS_HASH_SHA224_mode: PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES)); /* SHA224 size */ DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES)); break; case CRYS_HASH_SHA256_mode: PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES)); /* SHA256 size */ DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES)); break; case CRYS_HASH_SHA384_mode: PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES)); /* SHA384 size */ DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES)); break; case CRYS_HASH_SHA512_mode: PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES)); /* SHA512 size */ DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES)); break; default: break; } return (CRYS_OK); }
CRYSError_t CRYS_RSA_BER_BerEncoder( DxUint8_t **Buffer_ptr, DxUint8_t *BufferSize, DxUint16_t BufferTotalSize, BerParserObj_t *BerParserObj_ptr) { /* The structure of the buffer that need to be formated step 1 : [30 = Object TAG] step 2 : [ Total size ] step 2.1: [30 = Object TAG] step 2.2: [ The Size of the Digest Algo info upto 00] step 3 : [06 = Object TAG] step 4 : [The size of Digest Alg ] step 5 : [The Digest Alg ident] step 6 : [05] [00] | [04] step 7 : [The Size of Message Digest] step 8 : [ The Message digest ] */ static const DxUint8_t AlgorithmID_MD5_V2[] ={0x2A,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05}; static const DxUint8_t AlgorithmID_SHA[] ={0x2b,0x0e,0x03,0x02,0x1a}; static const DxUint8_t AlgorithmID_SHA224[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04}; static const DxUint8_t AlgorithmID_SHA256[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01}; static const DxUint8_t AlgorithmID_SHA384[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02}; static const DxUint8_t AlgorithmID_SHA512[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03}; DxUint8_t TotalSize=0; DxUint8_t *BufferInt_ptr; DxUint8_t MDSize = (DxUint8_t)(BerParserObj_ptr->MessageDigestSize); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED DxUint8_t TotalSizeTmp; #endif BufferInt_ptr=*Buffer_ptr+BufferTotalSize; PLAT_LOG_DEV_PRINT(( 25 ," \nStart Printing from CRYS_RSA_BER_BerEncoder\n" )); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe input buffer pointer (*Buffer_ptr) = " ,(DxUint8_t *)*Buffer_ptr,*BufferSize)); PLAT_LOG_DEV_PRINT(( 25 ," \nThe input buffer pointer after copy (BufferInt_ptr)= %p \n", BufferInt_ptr)); PLAT_LOG_DEV_PRINT(( 25 ," \nTotal size = %d \n", BufferTotalSize)); /* step 8 : Set the MD at the end of the buffer */ BufferInt_ptr-= MDSize; DX_VOS_FastMemCpy(BufferInt_ptr, BerParserObj_ptr->MessageDigest_ptr, MDSize); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 8 - adding MD = " ,(DxUint8_t *)BufferInt_ptr,MDSize)); /****************************************************************** * Need to check the type of the size ( at this stage its 1 octet) ******************************************************************/ /* step 7 */ BufferInt_ptr-=1; *BufferInt_ptr=MDSize; #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp = CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES +1 ; /* TotalSizeTmp+=1;*/ PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 7 - adding MD size " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif /* step 6 */ BufferInt_ptr-= 3; *(BufferInt_ptr+0)=0x05; *(BufferInt_ptr+1)=0x00; *(BufferInt_ptr+2)=0x04; #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=3; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 6 - adding 050004 = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif /*step 5 + 4 */ switch(BerParserObj_ptr->DigestAlg){ case CRYS_HASH_MD5_mode: PLAT_LOG_DEV_PRINT(( 25 ," \nCRYS_ALG_HASH_MD_5 size = %d pointer before %p \n",sizeof(AlgorithmID_MD5_V2),BufferInt_ptr)); BufferInt_ptr-=sizeof(AlgorithmID_MD5_V2); PLAT_LOG_DEV_PRINT(( 25 ," \n BufferInt_ptr after = %p \n",BufferInt_ptr)); DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_MD5_V2,sizeof(AlgorithmID_MD5_V2)); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=sizeof(AlgorithmID_MD5_V2); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif BufferInt_ptr-=1; /* step 4 */ *BufferInt_ptr=sizeof(AlgorithmID_MD5_V2); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=1; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif TotalSize+=sizeof(AlgorithmID_MD5_V2); break; case CRYS_HASH_SHA1_mode: PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_1 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA),BufferInt_ptr)); BufferInt_ptr-=sizeof(AlgorithmID_SHA); PLAT_LOG_DEV_PRINT(( 25 ," \n BufferInt_ptr after = %p \n",BufferInt_ptr)); DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA,sizeof(AlgorithmID_SHA)); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=TotalSizeTmp; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif BufferInt_ptr-=1; /* step 4 */ *BufferInt_ptr=sizeof(AlgorithmID_SHA); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=1; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif TotalSize+=sizeof(AlgorithmID_SHA); break; case CRYS_HASH_SHA224_mode: PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_224 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA224),BufferInt_ptr)); BufferInt_ptr-=sizeof(AlgorithmID_SHA224); PLAT_LOG_DEV_PRINT(( 25 ," \n BufferInt_ptr after = %p \n",BufferInt_ptr)); DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA224,sizeof(AlgorithmID_SHA224)); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=TotalSizeTmp; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif BufferInt_ptr-=1; /* step 4 */ *BufferInt_ptr=sizeof(AlgorithmID_SHA224); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=1; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif TotalSize+=sizeof(AlgorithmID_SHA224); break; case CRYS_HASH_SHA256_mode: PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_256 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA256),BufferInt_ptr)); BufferInt_ptr-=sizeof(AlgorithmID_SHA256); PLAT_LOG_DEV_PRINT(( 25 ," \n BufferInt_ptr after = %p \n",BufferInt_ptr)); DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA256,sizeof(AlgorithmID_SHA256)); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=TotalSizeTmp; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif BufferInt_ptr-=1; /* step 4 */ *BufferInt_ptr=sizeof(AlgorithmID_SHA256); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=1; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif TotalSize+=sizeof(AlgorithmID_SHA256); break; case CRYS_HASH_SHA384_mode: PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_384 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA384),BufferInt_ptr)); BufferInt_ptr-=sizeof(AlgorithmID_SHA384); PLAT_LOG_DEV_PRINT(( 25 ," \n BufferInt_ptr after = %p \n",BufferInt_ptr)); DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA384,sizeof(AlgorithmID_SHA384)); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=TotalSizeTmp; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif BufferInt_ptr-=1; /* step 4 */ *BufferInt_ptr=sizeof(AlgorithmID_SHA384); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=1; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif TotalSize+=sizeof(AlgorithmID_SHA384); break; case CRYS_HASH_SHA512_mode: PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_512 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA512),BufferInt_ptr)); BufferInt_ptr-=sizeof(AlgorithmID_SHA512); PLAT_LOG_DEV_PRINT(( 25 ," \n BufferInt_ptr after = %p \n",BufferInt_ptr)); DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA512,sizeof(AlgorithmID_SHA512)); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=TotalSizeTmp; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif BufferInt_ptr-=1; /* step 4 */ *BufferInt_ptr=sizeof(AlgorithmID_SHA512); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=1; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif TotalSize+=sizeof(AlgorithmID_SHA512); break; default : PLAT_LOG_DEV_PRINT(( 25 ," \n Error in BerParserObj_ptr->HashType = %d ",BerParserObj_ptr->DigestAlg)); return CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR; } /* step 3 */ BufferInt_ptr-=1; *BufferInt_ptr=0x06; #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp+=1; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 3 - adding 06 = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif /* step 2.2 */ BufferInt_ptr-=1; *BufferInt_ptr = (DxUint8_t)(TotalSize + 4); /* total size stores the step5 size */ /* step 2.1 */ BufferInt_ptr-=1; *BufferInt_ptr =0x30; /* step 2 */ BufferInt_ptr-=1 ; *BufferInt_ptr= (DxUint8_t)(4 + TotalSize+ 4 + MDSize); #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED TotalSizeTmp=*BufferInt_ptr; PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 2 - adding total size of buffer = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp)); #endif *BufferSize=(DxUint8_t)(*BufferInt_ptr+2); /* The +1 is for the octet of the suze and +1 is for the octet 30 that will be added in the next step */ /* step 1 */ BufferInt_ptr-=1; *BufferInt_ptr=0x30 ; /********************************** * At this point BufferInt_ptr points to the start of the data to send to **********************************/ *Buffer_ptr=BufferInt_ptr; PLAT_LOG_DEV_PRINT(( 25 ," \n The input buffer pointer (*Buffer_ptr) = %p",*Buffer_ptr)); PLAT_LOG_DEV_PRINT(( 25 ," \n The input buffer pointer (**Buffer_ptr )= %p",**Buffer_ptr)); PLAT_LOG_DEV_PRINT(( 25 ," \nThe input buffer pointer after copy (BufferInt_ptr)= %p",BufferInt_ptr)); PLAT_LOG_DEV_PRINT(( 25 ," \nTotal size = %d",*BufferSize)); PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after formating = " ,(DxUint8_t *)BufferInt_ptr,CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES)); return CRYS_RSA_BER_ENCODING_OK ; }
/** Function Name: CRYS_RSA_PKCS1_v1_5_Encode Date: 18-01-2005 Author: Ohad Shperling \brief CRYS_RSA_PKCS1_v1_5_Encode implements EME-PKCS1_v1_5_Encoding algorithm as defined in PKCS#1 v1.5 Sec 8.1 @param[in] K - The modulus size denoted in octets. @param[in] M_ptr - Pointer to the Message to pad the ouput stream @param[in] MSize - Denotes the Message size @param[in] BlockType - BlockType for PUB Key is 02 BlockType for Priv Key is 01 @param[out] Output_ptr - Pointer to a buffer which is at least K octets long @return CRYSError_t - CRYS_OK, */ CRYSError_t CRYS_RSA_PKCS1_v1_5_Encode(DxUint16_t K, CRYS_PKCS1_Block_Type BlockType, DxUint8_t *M_ptr, DxUint32_t MSize, DxUint8_t *Output_ptr) { /* The return error identifier */ CRYSError_t Error; /* Padding String Size */ DxUint16_t PSSize,I,J; /* FUNCTION LOGIC */ /* .................. initializing local variables ................... */ /* ------------------------------------------------------------------- */ /* initializing the Error to O.K */ Error = CRYS_OK; /*Initializing the EB buffer to zero*/ DX_VOS_MemSet(Output_ptr,0x0,K); /* ............... checking the parameters validity ................... */ /* -------------------------------------------------------------------- */ if(MSize>(DxUint32_t)(K-11)) return CRYS_RSA_ENCODE_15_MSG_OUT_OF_RANGE; /*-------------------------------------------*/ /* */ /* Step 1 : Encryption block formating */ /* */ /* 00 || BT || PS || 00 || D */ /* MSByte LSByte */ /* Note: - */ /* - BT for PUBKey is 02 */ /* - PS size is k-3-||D|| , padding */ /* value is pseudorandomly non */ /* zero */ /*-------------------------------------------*/ Output_ptr[0]=0x00; /* set the 00 */ Output_ptr[1]=BlockType; /* set Block Type */ PSSize=(DxUint16_t)(K-3-MSize); /* In PKCS#1 V2 : The padding string PS in EME-PKCS1-v1_5 is at least eight octets long, which is a security condition for public-key operations that prevents an attacker from recovering data by trying all possible encryption blocks. */ if(PSSize<0x08) { return CRYS_RSA_ENCODE_15_PS_TOO_SHORT; } switch(BlockType) { case CRYS_RSA_PKCS1_15_MODE00: /* Please refer to PKCS1 Ver 1.5 Standart for the security argument why not to use this kind of Block Type*/ return CRYS_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED ; case CRYS_RSA_PKCS1_15_MODE01: DX_VOS_MemSet(&Output_ptr[2],0xFF,PSSize); break; case CRYS_RSA_PKCS1_15_MODE02: Error = CRYS_RND_GenerateVector((DxUint16_t)(K-2),&Output_ptr[2]); if(Error != CRYS_OK) { return Error; } /*The random generation should not generate a zero octet according to the standart*/ J = K-2; for(I=2;I<PSSize+2;I++) { if(Output_ptr[I] == 0x00) { /*Take a non zero octet from the end of the vector*/ while(Output_ptr[J] == 0) { J--; continue; } /*Change the zero octet*/ Output_ptr[I] = Output_ptr[J]; J--; } if(J == I) { /*This happens in very low probability*/ /*All the extra random generated octets are zero or used*/ /*regenerate */ Error = CRYS_RND_GenerateVector((DxUint16_t)(K-2),&Output_ptr[2]); if(Error != CRYS_OK) { return Error; } J = K-2; I=1;/*go back to the start of the loop*/ } } break; default: return CRYS_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED; } /* add 00 */ Output_ptr[K-MSize-1]=0x00; /* copy the data */ DX_VOS_FastMemCpy(&Output_ptr[K-MSize],M_ptr,MSize); return CRYS_OK; }