TA的每日心情 | 开心 2017-7-4 13:51 |
---|
签到天数: 347 天 连续签到: 1 天 [LV.8]以坛为家I
|
通常对代码的加密保护有硬件加密方式和软件加密方式。
AES是通常比较常用的一种有效加密方式
什么是AES加密?
从概念上来说
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
Rijndael密码的设计力求满足以下3条标准:
① 抵抗所有已知的攻击。
② 在多个平台上速度快,编码紧凑。
③ 设计简单。
当前的大多数分组密码,其轮函数是Feistel结构。
Rijndael没有这种结构。
Rijndael轮函数是由3个不同的可逆均匀变换
严格地说,AES和Rijndael加密法并不完全一样(虽然在实际应用中二者可以互换),因为Rijndael加密法可以支持更大范围的区块和密钥长度:AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特;而Rijndael使用的密钥和区块长度可以是32位的整数倍,以128位为下限,256比特为上限。加密过程中使用的密钥是由Rijndael密钥生成方案产生。
大多数AES计算是在一个特别的有限域完成的。
AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“状态(state)”,其初值就是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。(Rijndael加密法因支持更大的区块,其矩阵行数可视情况增加)加密时,各轮AES加密循环(除最后一轮外)均包含4个步骤:
AddRoundKey — 矩阵中的每一个字节都与该次轮秘钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
SubBytes — 通过个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
ShiftRows — 将矩阵中的每个横列进行循环式移位。
MixColumns — 为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的四个字节。
最后一个加密循环中省略MixColumns步骤,而以另一个AddRoundKey取代。
更为深入的说明可以看看度娘O(∩_∩)O~
从实用角度来说,咱还是看看具体程序
atmel还是比较贴心的,居然给出了基于atmel芯片的加密例程
咱来实际体验下
先看看主函数
int main(void){ uint8_t key; /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console */ configure_console(); /* Output example information */ printf("-- AES Example --\r\n"); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); /* Enable the AES module. */ aes_get_config_defaults(&g_aes_cfg); aes_init(AES, &g_aes_cfg); aes_enable(); /* Enable AES interrupt. */ aes_set_callback(AES, AES_INTERRUPT_DATA_READY, aes_callback, 1); /* Display menu */ display_menu(); while (1) { scanf("%c", (char *)&key); switch (key) { case 'h': display_menu(); break; case '1': printf("ECB mode encryption and decryption test.\r\n"); ecb_mode_test(); break; case '2': printf("CBC mode encryption and decryption test.\r\n"); cbc_mode_test(); break; case '3': printf("CFB128 mode encryption and decryption test.\r\n"); cfb128_mode_test(); break; case '4': printf("OFB mode encryption and decryption test.\r\n"); ofb_mode_test(); break; case '5': printf("CTR mode encryption and decryption test.\r\n"); ctr_mode_test(); break; case 'd': #if SAM4E printf( "ECB mode encryption and decryption test with DMA.\r\n"); ecb_mode_test_dma(); #else printf("This mode is not supported by device.\r\n"); #endif break; case 'p': #if SAM4C || SAM4CP || SAM4CM printf( "ECB mode encryption and decryption test with PDC.\r\n"); ecb_mode_test_pdc(); #else printf("This mode is not supported by device.\r\n"); #endif break; default: break; } }}主要两部分,使能AES模式和使能AES中断程序模块化集成的很不错,调用很方便
具体的函数在aes.c文件中
void aes_set_callback( Aes *const p_aes, aes_interrupt_source_t source, aes_callback_t callback, uint8_t irq_level){ /* Validate arguments. */ Assert(p_aes); if (source == AES_INTERRUPT_DATA_READY) { aes_callback_pointer[0] = callback; } else if (source == AES_INTERRUPT_UNSPECIFIED_REGISTER_ACCESS) { aes_callback_pointer[1] = callback; } #if SAM4C || SAM4CP || SAM4CM else if (source == AES_INTERRUPT_END_OF_RECEIVE_BUFFER) { aes_callback_pointer[2] = callback; } else if (source == AES_INTERRUPT_END_OF_TRANSMIT_BUFFER) { aes_callback_pointer[3] = callback; } else if (source == AES_INTERRUPT_RECEIVE_BUFFER_FULL) { aes_callback_pointer[4] = callback; } else if (source == AES_INTERRUPT_TRANSMIT_BUFFER_FULL) { aes_callback_pointer[5] = callback; }#elif SAMV70 || SAMV71 || SAME70 || SAMS70 else if ((source == AES_INTERRUPT_TAG_READY)) { aes_callback_pointer[2] = callback; }#endif /* SAM4C || SAM4CP || SAM4CM */ irq_register_handler((IRQn_Type)AES_IRQn, irq_level); aes_enable_interrupt(p_aes, source);}详细的AES中断处理void AES_Handler(void){ uint32_t status = aes_read_interrupt_status(AES); uint32_t mask = aes_read_interrupt_mask(AES); if ((status & AES_ISR_DATRDY) && (mask & AES_IMR_DATRDY)) { if (aes_callback_pointer[0]) { aes_callback_pointer[0](); } } if ((status & AES_ISR_URAD) && (mask & AES_IMR_URAD)) { if (aes_callback_pointer[1]) { aes_callback_pointer[1](); } }#if SAM4C || SAM4CP || SAM4CM if ((status & AES_ISR_ENDRX) && (mask & AES_IMR_ENDRX)) { if (aes_callback_pointer[2]) { aes_callback_pointer[2](); } } if ((status & AES_ISR_ENDTX) && (mask & AES_IMR_ENDTX)) { if (aes_callback_pointer[3]) { aes_callback_pointer[3](); } } if ((status & AES_ISR_RXBUFF) && (mask & AES_IMR_RXBUFF)) { if (aes_callback_pointer[4]) { aes_callback_pointer[4](); } } if ((status & AES_ISR_TXBUFE) && (mask & AES_IMR_TXBUFE)) { if (aes_callback_pointer[5]) { aes_callback_pointer[5](); } }#elif SAMV70 || SAMV71 || SAME70 || SAMS70 if ((status & AES_IER_TAGRDY) && (mask & AES_IER_TAGRDY)) { if (aes_callback_pointer[2]) { aes_callback_pointer[2](); } }#endif /* SAM4C || SAM4CP || SAM4CM */}其实还是通过算法调用指定的数组,不停的数据变化整个工程很多的定义和一层层的数据处理,还是算法啊,写的不错,感兴趣的可以一起研究下 |
|