#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; | |
} | |
} | |