XTS-AES

本文介绍了在块存储设备上加密数据的IEEE P1619标准,并重点解析了XTS-AES加密模式的特点及其在TrueCrypt、OpenBSD/FreeBSD DiskEncryption及MacOSX FileVault中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AES加密算法, 不说了。

block cipher的各种工作模式,ECB、CBC、Counter等,不说了。

 

Cipher在用作disk encryption的时候,也有许多问题要考虑。主要是ECB模式不行(很明显),CBC模式也不好(无法随机访问),所以IEEE标准化了一个P1619标准,IEEE Standard for Cryptographic Protection of Data on Block-Oriented Storage Devices,见http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4493431

以及wiki页面http://en.wikipedia.org/wiki/IEEE_P1619

 

其中提出了一个名为XTS-AES的encryption mode作为加密模式,特点是:

1,disk block(如一个扇区)分成多个cipher block(如AES-128的128bit);

2,各cipher block之间独立(没有CBC那样的dependency);

3,cipher block的加密输入包含了index信息(扇区号和块号);

 

更详细信息,可参见TrueCrypt的介绍:

http://www.truecrypt.org/docs/?s=modes-of-operation

 

这个加密模式被用于TrueCyrpt、OpenBSD/FreeBSD的Disk Encryption,以及Mac OS X的FileVault。

更多信息参见wiki页面:

http://en.wikipedia.org/wiki/Disk_encryption_theory

 

XTS-AES是可以随机访问的,其加密解密也是可以并行化的(类似于ECB或Counter模式),例如TrueCrypt强调的Parallelization

http://www.truecrypt.org/docs/?s=parallelization


#include "xts.h" #include "aes.h" static inline void copy_block(aes_block_t dest, const aes_block_t src) { int i, j; for(i = 0; i < Nb; i++) for(j = 0; j < 4; j++) dest[i][j] = src[i][j]; } static inline void xor_block(aes_block_t dest, const aes_block_t other) { int i, j; for(i = 0; i < Nb; i++) for(j = 0; j < 4; j++) dest[i][j] ^= other[i][j]; } /* static void mul_a(aes_block_t block) { /*int x, y; uint8_t cin, cout; for(x = 0; x < 4; x++) { for(y = 0, cin = 0; y < 4; y++) { cout = block[x][y] >> 7; block[x][y] <<= 1; block[x][y] |= cin; cin = cout; } } if(cout) block[0][0] ^= 0x87; uint8_t i = 16; uint8_t carry = block[3][3] & 0x80; while(--i) { uint8_t prev = block[(i - 1) / 4][(i - 1) % 4]; uint8_t val = block[i / 4][i % 4]; block[i / 4][i % 4] = (val << 1) | (prev & 0x80 ? 1 : 0); } block[0][0] = (block[0][0] << 1) ^ (carry ? 0x87 : 0); } */ static void mul_a(aes_block_t block) { uint8_t* bytes = (uint8_t*)block; uint8_t carry = 0; // 大端处理:从最高字节(byte0)开始 for (int i = 0; i < 16; i++) { uint8_t msb = bytes[i] >> 7; // 保存当前字节最高位 bytes[i] = (bytes[i] << 1) | carry; carry = msb; } // 溢出处理:异或0x87到最低字节 if (carry) bytes[15] ^= 0x87; } static void mul_a_exp(aes_block_t block, uint64_t i) { uint64_t iter; for(iter = 0; iter < i; iter++) mul_a(block); } static void xts_enc_block(aes_block_t block, aes_key_schedule w, aes_block_t tweak) { xor_block(block, tweak); aes_enc_block(block, w); xor_block(block, tweak); } static void xts_dec_block(aes_block_t block, aes_key_schedule w, aes_block_t tweak) { xor_block(block, tweak); aes_dec_block(block, w); xor_block(block, tweak); } void xts_aes_enc(uint8_t *P, size_t pl, const uint8_t *K, uint64_t i) { uint8_t b = pl % 16; uint64_t q; size_t m, n_blocks; aes_block_t tweak, *blocks; aes_key_t K1, K2; aes_key_schedule wK1, wK2; /* K = K1 | K2 */ for(q = 0; q < 4 * Nk; q++) { K1[q / 4][q % 4] = K[q]; K2[q / 4][q % 4] = K[(4 * Nk) + q]; } aes_fill_block((uint8_t*) &i, 8, tweak); n_blocks = aes_fill_blocks(P, pl, &blocks); m = !b ? n_blocks : n_blocks - 1; aes_gen_key_schedule(K1, wK1); aes_gen_key_schedule(K2, wK2); aes_enc_block(tweak, wK2); for(q = 0; m >= 2 && q <= m - 2; q++) { xts_enc_block(blocks[q], wK1, tweak); mul_a(tweak); } if(b == 0) { xts_enc_block(blocks[m - 1], wK1, tweak); } else { int x, y, c; aes_block_t CC, PP; copy_block(CC, blocks[m - 1]); xts_enc_block(CC, wK1, tweak); mul_a(tweak); copy_block(PP, blocks[m]); for(c = 16 - b; c < 16 ; c++) /* I think this initializes it right */ { PP[c / 4][c % 4] = CC[c / 4][c % 4]; } for(x = 0; x < 4 && c < b; x++) for(y = 0; y < 4 && c < b; y++, b++) blocks[m][x][y] = CC[x][y]; copy_block(blocks[m - 1], PP); xts_enc_block(blocks[m - 1], wK1, tweak); } for(m = 0; m < n_blocks - 1; m++) { aes_empty_block(blocks[m], &P[16 * m], 16); } aes_empty_block(blocks[m], &P[16 * m], b == 0 ? 16 : b); } void xts_aes_dec(uint8_t *P, size_t pl, const uint8_t *K, uint64_t i) { uint8_t b = pl % 16; uint64_t q; size_t m, n_blocks; aes_block_t tweak, *blocks; aes_key_t K1, K2; aes_key_schedule wK1, wK2; for(q = 0; q < 4 * Nk; q++) { K1[q / 4][q % 4] = K[q]; K2[q / 4][q % 4] = K[(4 * Nk) + q]; } aes_fill_block((uint8_t*) &i, 8, tweak); n_blocks = aes_fill_blocks(P, pl, &blocks); m = !b ? n_blocks : n_blocks - 1; aes_gen_key_schedule(K1, wK1); aes_gen_key_schedule(K2, wK2); aes_enc_block(tweak, wK2); for(q = 0; m >= 2 && q <= m - 2; q++) { xts_dec_block(blocks[q], wK1, tweak); mul_a(tweak); } if(b == 0) { xts_dec_block(blocks[m - 1], wK1, tweak); } else { int x, y, c; aes_block_t CC, PP, tweak_m; copy_block(tweak_m, tweak); mul_a(tweak_m); copy_block(PP, blocks[m - 1]); xts_dec_block(PP, wK1, tweak_m); copy_block(CC, blocks[m]); for(c = 16 - b; c < 16; c++) { CC[c / 4][c % 4] = PP[c / 4][c % 4]; } for(x = 0; x < Nb; x++) for(y = 0; y < 4; y++) blocks[m][x][y] = PP[x][y]; xts_dec_block(CC, wK1, tweak); } for(m = 0; m < n_blocks - 1; m++) aes_empty_block(blocks[m], &P[16 * m], 16); aes_empty_block(blocks[m], &P[16 * m], b == 0 ? 16 : b); } 这个XTS-AES的实现对吗
最新发布
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值