blob: 702cb532cf2243fa43c6325c3309859659fb04c1 [file] [log] [blame]
#include "drv_rsa.h"
#include <sdio.h>
/* º¯Êý¹¦ÄÜ: ʵÏÖ- N^-1 mod 2^32 µÄËã·¨*/
static u32 get_N_inv(u32 N0)
{
u32 N_inv=1;
u32 i,a,b;
for(i=1; i<32; i++)
{
a = 1<<i;
b = (N0*N_inv)&((2<<i)-1);
if(a<b)
{
N_inv = N_inv+ a;
}
}
return (0xffffffff-N_inv+1);
}
static void rsa_WriteDataToReg(u32* pudAddr, u32 udReg, u32 Len)
{
u32 udI;
for(udI=0;udI<Len;udI++)
{
//Ä£¿éµÍµØÖ·¼Ä´æÆ÷´æ·ÅµÍµØÖ·Êý¾Ý£¬Êý¾Ý´æ·ÅÊǵ͵ØÖ··Å¸ßλÊý¾Ý
REG32(udReg + udI*4) = *(pudAddr+Len-1-udI);
}
}
static void rsa_ReadDataFromReg(u32* pudAddr, u32 udReg, u32 Len)
{
u32 udI;
for(udI=0;udI<Len;udI++)
{
//Ä£¿éµÍµØÖ·¼Ä´æÆ÷´æ·ÅµÍµØÖ·Êý¾Ý£¬Êý¾Ý´æ·ÅÊǵ͵ØÖ··Å¸ßλÊý¾Ý
*(pudAddr+Len-1-udI) = REG32(udReg + udI*4);
}
}
#ifdef RSA_CODE_SUPPORT_ALL
/**-------------------------------------------------------------------------------------------------------------------@n
* @brief ´óÊý³Ë·¨¼ÆËã
*
* ¹¦ÄÜÏêÊö:
* - Rsa_BigNumMultipleº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
* - ¼ÆËãÁ½¸ö´óÊýÏà³Ë
*
* ²ÎÊý¸ÅÊö:
*
*
* ·µ »Ø Öµ: ÎÞ
*
*--------------------------------------------------------------------------------------------------------------------*/
static u32 rsa_BigNumMultiple(u32 udNbitLen, u32* pudInputM, u32* pudInputE, u32* pudOutputP)
{
u32 Nlen_word, Elen_word;
//input M, E, udNbitLen
if(udNbitLen>2048||udNbitLen==0\
||pudInputM==NULL||pudInputE==NULL||pudOutputP==NULL)
{
return 1;
}
REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
REG32(RSA_CALC_MODE) = RSA_BIG_NUM_MULTIPLE; /* set computemode*/
//ÅäÖÃM,E µ½RAM¼Ä´æÆ÷ÖÐ
Nlen_word = (udNbitLen+31)/32;
rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Nlen_word);
//ÅäÖÃN µÄbit ³¤¶È
REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
//enable compute
REG32(RSA_MODULE_ENABLE) = 1;
/*check interrupt status, waiting for calculating finished*/
while(!(REG32(RSA_INT_STATUS)& 0x01));
/* clear the interrupt,input any */
REG32(RSA_INT_STATUS) = 1;
/* read the result */
rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
/*close mode enable*/
REG32(RSA_MODULE_ENABLE) = 0;
return 0;
}
/**-------------------------------------------------------------------------------------------------------------------@n
* @brief ³õʼ»¯¼ÆËã
*
* ¹¦ÄÜÏêÊö:
* - Rsa_InitComputeº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
* - ³õʼ»¯¼ÆËã c= r*r mod N
*
* ²ÎÊý¸ÅÊö:
*
*
* ·µ »Ø Öµ: ÎÞ
*
*--------------------------------------------------------------------------------------------------------------------*/
static u32 rsa_InitCompute(u32 udNbitLen, u32* pudInputN, u32* pudOutputP)
{
u32 Nlen_word;
//input N, udNbitLen
if(udNbitLen>2048||udNbitLen==0\
||pudInputN==NULL||pudOutputP==NULL)
{
return 1;
}
REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
REG32(RSA_CALC_MODE) = RSA_INIT_COMPUTE; /* set computemode*/
//ÅäÖÃN µ½RAM¼Ä´æÆ÷ÖÐ
Nlen_word = (udNbitLen+31)/32;
rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
//ÅäÖÃN µÄbit ³¤¶È
if((pudInputN[0]&0x80000000) == 0)
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen-2;/*set modelength, µ¥Î»bit*/
}
else
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
}
//enable compute
REG32(RSA_MODULE_ENABLE) = 1;
/*check interrupt status, waiting for calculating finished*/
while(!(REG32(RSA_INT_STATUS)& 0x01));
/* clear the interrupt,input any */
REG32(RSA_INT_STATUS) = 1;
/* read the result */
rsa_ReadDataFromReg(pudOutputP, RSA_INIT_CALC_RAM, Nlen_word);
/*close mode enable*/
REG32(RSA_MODULE_ENABLE) = 0;
return 0;
}
/**-------------------------------------------------------------------------------------------------------------------@n
* @brief ²»´ø³õʼ»¯¼ÆËãµÄÄ£³Ë
*
* ¹¦ÄÜÏêÊö:
* - Rsa_ModMultipleNoInitº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
* - ÔÚÄ£³ËÖУ¬²»½øÐгõʼ»¯¼ÆËã
*
* ²ÎÊý¸ÅÊö:
*
*
* ·µ »Ø Öµ: ÎÞ
*
*--------------------------------------------------------------------------------------------------------------------*/
static void rsa_ModMultipleNoInit(u32 udNbitLen, u32 udEbitLen, u32* pudInputM, u32* pudInputE, u32* pudInputN, u32* pudInputC, u32* pudOutputP)
{
u32 Nlen_word, Elen_word;
//input M, E, N, C, udNbitLen, udEbitLen
if(udNbitLen>2048||udNbitLen==0||udEbitLen>2048||udEbitLen==0\
||pudInputM==NULL||pudInputE==NULL||pudInputN==NULL||pudInputC==NULL||pudOutputP==NULL)
{
return 1;
}
REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
REG32(RSA_CALC_MODE) = RSA_MOD_MULTIPLE_NO_INIT; /* set computemode*/
Nlen_word = (udNbitLen+31)/32;
Elen_word = (udEbitLen+31)/32;
//ÉèÖòÎÊýN0, µÈÓÚ²ÎÊýN µÄ×îµÍλ
REG32(RSA_NZORE) = pudInputN[Nlen_word-1];
// ÉèÖòÎÊýN0' , µÈÓÚ- N^-1 mod 2^32
REG32(RSA_NZORE_INV) = get_N_inv(pudInputN[Nlen_word-1]);
//ÅäÖÃM,E,N µ½RAM¼Ä´æÆ÷ÖÐ
rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Elen_word);
rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
rsa_WriteDataToReg(pudInputC, RSA_INIT_CALC_RAM, Nlen_word);
//ÅäÖÃN,E µÄbit ³¤¶È
if((pudInputN[0]&0x80000000) == 0)
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen-2;/*set modelength, µ¥Î»bit*/
}
else
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
}
REG32(RSA_EXP_LENGTH) = (Elen_word-1)<<5; /*set expolength, µ¥Î»word*/
//enable compute
REG32(RSA_MODULE_ENABLE) = 1;
/*check interrupt status, waiting for calculating finished*/
while(!(REG32(RSA_INT_STATUS)& 0x01));
/* clear the interrupt,input any */
REG32(RSA_INT_STATUS) = 1;
/* read the result */
rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
/*close mode enable*/
REG32(RSA_MODULE_ENABLE) = 0;
return 0;
}
/**-------------------------------------------------------------------------------------------------------------------@n
* @brief ´ø³õʼ»¯¼ÆËãµÄÄ£³Ë
*
* ¹¦ÄÜÏêÊö:
* - Rsa_ModMultipleWithInitº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
* - ÔÚÄ£³ËÖУ¬½øÐгõʼ»¯¼ÆËã
*
* ²ÎÊý¸ÅÊö:
*
*
* ·µ »Ø Öµ: ÎÞ
*
*--------------------------------------------------------------------------------------------------------------------*/
static u32 rsa_ModMultipleWithInit(u32 udNbitLen, u32 udEbitLen, u32* pudInputM, u32* pudInputE, u32* pudInputN, u32* pudOutputP)
{
u32 Nlen_word, Elen_word;
//input M, E, N, udNbitLen, udEbitLen
if(udNbitLen>2048||udNbitLen==0||udEbitLen>2048||udEbitLen==0\
||pudInputM==NULL||pudInputE==NULL||pudInputN==NULL||pudOutputP==NULL)
{
return 1;
}
REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
REG32(RSA_CALC_MODE) = RSA_MOD_MULTIPLE_WITH_INIT; /* set computemode*/
Nlen_word = (udNbitLen+31)/32;
Elen_word = (udEbitLen+31)/32;
//ÉèÖòÎÊýN0, µÈÓÚ²ÎÊýN µÄ×îµÍλ
REG32(RSA_NZORE) = pudInputN[Nlen_word-1];
// ÉèÖòÎÊýN0' , µÈÓÚ- N^-1 mod 2^32
REG32(RSA_NZORE_INV) = get_N_inv(pudInputN[Nlen_word-1]);
//ÅäÖÃM,E,N µ½RAM¼Ä´æÆ÷ÖÐ
rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Elen_word);
rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
//ÅäÖÃN,E µÄbit ³¤¶È
if((pudInputN[0]&0x80000000) == 0)
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen-2;/*set modelength, µ¥Î»bit*/
}
else
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
}
REG32(RSA_EXP_LENGTH) = (Elen_word-1)<<5; /*set expolength, µ¥Î»word*/
//enable compute
REG32(RSA_MODULE_ENABLE) = 1;
/*check interrupt status, waiting for calculating finished*/
while(!(REG32(RSA_INT_STATUS)& 0x01));
/* clear the interrupt,input any */
REG32(RSA_INT_STATUS) = 1;
/* read the result */
rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
/*close mode enable*/
REG32(RSA_MODULE_ENABLE) = 0;
return 0;
}
/**-------------------------------------------------------------------------------------------------------------------@n
* @brief ²»´ø³õʼ»¯¼ÆËãµÄÄ£ÃÝÔËËã
*
* ¹¦ÄÜÏêÊö:
* - Rsa_ModExpoNoInitº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
* - ÔÚÄ£ÃÝÔËËãÖУ¬²»½øÐгõʼ»¯¼ÆËã
*
* ²ÎÊý¸ÅÊö:
*
*
* ·µ »Ø Öµ: ÎÞ
*
*--------------------------------------------------------------------------------------------------------------------*/
static u32 rsa_ModExpoNoInit(u32 udNbitLen, u32 udEbitLen, u32* pudInputM, u32* pudInputE, u32* pudInputN, u32* pudInputC, u32* pudOutputP)
{
u32 Nlen_word, Elen_word;
//input M, E, N, C, udNbitLen, udEbitLen
if(udNbitLen>2048||udNbitLen==0||udEbitLen>2048||udEbitLen==0\
||pudInputM==NULL||pudInputE==NULL||pudInputN==NULL||pudInputC==NULL||pudOutputP==NULL)
{
return 1;
}
REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
REG32(RSA_CALC_MODE) = RSA_MOD_EXPO_NO_INIT; /* set computemode*/
Nlen_word = (udNbitLen+31)/32;
Elen_word = (udEbitLen+31)/32;
//ÉèÖòÎÊýN0, µÈÓÚ²ÎÊýN µÄ×îµÍλ
REG32(RSA_NZORE) = pudInputN[Nlen_word-1];
// ÉèÖòÎÊýN0' , µÈÓÚ- N^-1 mod 2^32
REG32(RSA_NZORE_INV) = get_N_inv(pudInputN[Nlen_word-1]);
//ÅäÖÃM,E,N µ½RAM¼Ä´æÆ÷ÖÐ
rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Elen_word);
rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
rsa_WriteDataToReg(pudInputC, RSA_INIT_CALC_RAM, Nlen_word);
//ÅäÖÃN,E µÄbit ³¤¶È
if((pudInputN[0]&0x80000000) == 0)
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen-2;/*set modelength, µ¥Î»bit*/
}
else
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
}
REG32(RSA_EXP_LENGTH) = (Elen_word-1)<<5; /*set expolength, µ¥Î»word*/
//enable compute
REG32(RSA_MODULE_ENABLE) = 1;
/*check interrupt status, waiting for calculating finished*/
while(!(REG32(RSA_INT_STATUS)& 0x01));
/* clear the interrupt,input any */
REG32(RSA_INT_STATUS) = 1;
/* read the result */
rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
/*close mode enable*/
REG32(RSA_MODULE_ENABLE) = 0;
return 0;
}
#endif
/**-------------------------------------------------------------------------------------------------------------------@n
* @brief ´ø³õʼ»¯¼ÆËãµÄÄ£ÃÝÔËËã
*
* ¹¦ÄÜÏêÊö:
* - Rsa_ModExpoWithInitº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
* - ÔÚÄ£ÃÝÔËËãÖУ¬½øÐгõʼ»¯¼ÆËã
*
* ²ÎÊý¸ÅÊö:
*
*
* ·µ »Ø Öµ: ÎÞ
*
*--------------------------------------------------------------------------------------------------------------------*/
static u32 rsa_ModExpoWithInit(u32 udNbitLen, u32 udEbitLen, u32* pudInputM, u32* pudInputE, u32* pudInputN, u32* pudOutputP)
{
u32 Nlen_word, Elen_word;
//input M, E, N, udNbitLen, udEbitLen
if(udNbitLen>2048 || udNbitLen==0 || udEbitLen>2048 || udEbitLen==0\
|| pudInputM==NULL || pudInputE==NULL || pudInputN==NULL || pudOutputP==NULL)
{
return 1;
}
REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
REG32(RSA_CALC_MODE) = RSA_MOD_EXPO_WITH_INIT; /* set computemode*/
Nlen_word = (udNbitLen+31)/32;
Elen_word = (udEbitLen+31)/32;
//ÉèÖòÎÊýN0, µÈÓÚ²ÎÊýN µÄ×îµÍλ
REG32(RSA_NZORE) = pudInputN[Nlen_word-1];
// ÉèÖòÎÊýN0' , µÈÓÚ- N^-1 mod 2^32
REG32(RSA_NZORE_INV) = get_N_inv(pudInputN[Nlen_word-1]);
//ÅäÖÃM,E,N µ½RAM¼Ä´æÆ÷ÖÐ
rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Elen_word);
rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
//ÅäÖÃN,E µÄbit ³¤¶È
if((pudInputN[0] & 0x80000000) == 0)
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen - 2;/*set modelength, µ¥Î»bit*/
}
else
{
REG32(RSA_MODULAR_LENGTH) = udNbitLen - 1;/*set modelength, µ¥Î»bit*/
}
REG32(RSA_EXP_LENGTH) = (Elen_word - 1) << 5; /*set expolength, µ¥Î»word*/
//enable compute
REG32(RSA_MODULE_ENABLE) = 1;
/*check interrupt status, waiting for calculating finished*/
while(!(REG32(RSA_INT_STATUS) & 0x01));
/* clear the interrupt,input any */
REG32(RSA_INT_STATUS) = 1;
/* read the result */
rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
/*close mode enable*/
REG32(RSA_MODULE_ENABLE) = 0;
return 0;
}
/*
¹¦ÄÜÏêÊö:RSA ¸÷ÖÖ¼ÆËãµÄ½Ó¿Úº¯Êý
¸÷²ÎÊý:
ptInput Ïê¼û½á¹¹Ìå˵Ã÷
*/
u32 Rsa_Calculate(T_Rsa_Paramter ptInput)
{
switch(ptInput.udCalMode)
{
#ifdef RSA_CODE_SUPPORT_ALL
case RSA_BIG_NUM_MULTIPLE: //input M, E, udNbitLen
return rsa_BigNumMultiple(ptInput.udNbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudOutputP);
case RSA_INIT_COMPUTE: //input N, udNbitLen
return rsa_InitCompute(ptInput.udNbitLen, ptInput.pudInputN, ptInput.pudOutputP);
case RSA_MOD_MULTIPLE_NO_INIT: //input M, E, N, C, udNbitLen, udEbitLen
return rsa_ModMultipleNoInit(ptInput.udNbitLen, ptInput.udEbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudInputN, ptInput.pudInputC, ptInput.pudOutputP);
case RSA_MOD_EXPO_NO_INIT: //input M, E, N, C, udNbitLen, udEbitLen
return rsa_ModExpoNoInit(ptInput.udNbitLen, ptInput.udEbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudInputN, ptInput.pudInputC, ptInput.pudOutputP);
case RSA_MOD_MULTIPLE_WITH_INIT: //input M, E, N, udNbitLen, udEbitLen
return rsa_ModMultipleWithInit(ptInput.udNbitLen, ptInput.udEbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudInputN, ptInput.pudOutputP);
#endif
case RSA_MOD_EXPO_WITH_INIT: //input M, E, N, udNbitLen, udEbitLen
return rsa_ModExpoWithInit(ptInput.udNbitLen, ptInput.udEbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudInputN, ptInput.pudOutputP);
default:
return 1;
}
}