试图了解Brian Gladman博士的AES-CTR实施。 (http://gladman.plushost.co.uk/oldsite/AES/aes-src-12-09-11.zip aes_modes.c 849行以后) 我读了CTR算法,但这个实现让我感到困惑。 我无法看到它与CTR模式算法的匹配程度。
if(b_pos)代码部分是什么?
我也不明白有条件的 b_pos< AES_BLOCK_SIZE&& LEN
因为(AES_BLOCK_SIZE&& len)将始终为1而len> 0. AES_BLOCK_SIZE是16。
if(b_pos)
{
memcpy(buf, cbuf, AES_BLOCK_SIZE);
if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
while(b_pos < AES_BLOCK_SIZE && len)
{
*obuf++ = *ibuf++ ^ buf[b_pos++];
--len;
}
if(len)
ctr_inc(cbuf), b_pos = 0;
}
AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx ctx[1])
{ unsigned char *ip;
int i, blen, b_pos = (int)(ctx->inf.b[2]);
uint_8t buf[BFR_LENGTH];
if(b_pos)
{
memcpy(buf, cbuf, AES_BLOCK_SIZE);
if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
while(b_pos < AES_BLOCK_SIZE && len)
{
*obuf++ = *ibuf++ ^ buf[b_pos++];
--len;
}
if(len)
ctr_inc(cbuf), b_pos = 0;
}
while(len)
{
blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen;
for(i = 0, ip = buf; i < (blen >> 4); ++i)
{
memcpy(ip, cbuf, AES_BLOCK_SIZE);
ctr_inc(cbuf);
ip += AES_BLOCK_SIZE;
}
if(blen & (AES_BLOCK_SIZE - 1))
memcpy(ip, cbuf, AES_BLOCK_SIZE), i++;
if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
i = 0; ip = buf;
while(i + AES_BLOCK_SIZE <= blen)
{
obuf[ 0] = ibuf[ 0] ^ ip[ 0]; obuf[ 1] = ibuf[ 1] ^ ip[ 1];
obuf[ 2] = ibuf[ 2] ^ ip[ 2]; obuf[ 3] = ibuf[ 3] ^ ip[ 3];
obuf[ 4] = ibuf[ 4] ^ ip[ 4]; obuf[ 5] = ibuf[ 5] ^ ip[ 5];
obuf[ 6] = ibuf[ 6] ^ ip[ 6]; obuf[ 7] = ibuf[ 7] ^ ip[ 7];
obuf[ 8] = ibuf[ 8] ^ ip[ 8]; obuf[ 9] = ibuf[ 9] ^ ip[ 9];
obuf[10] = ibuf[10] ^ ip[10]; obuf[11] = ibuf[11] ^ ip[11];
obuf[12] = ibuf[12] ^ ip[12]; obuf[13] = ibuf[13] ^ ip[13];
obuf[14] = ibuf[14] ^ ip[14]; obuf[15] = ibuf[15] ^ ip[15];
i += AES_BLOCK_SIZE;
ip += AES_BLOCK_SIZE;
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
}
while(i++ < blen)
*obuf++ = *ibuf++ ^ ip[b_pos++];
}
ctx->inf.b[2] = (uint_8t)b_pos;
return EXIT_SUCCESS;
}
答案 0 :(得分:1)
CTR模式使AES能够像流密码一样工作。在加密和解密时,对数据长度没有限制,特别是在块对齐方面(与其他模式一样,如CBC)。
可以使用任意长度的输入数据(aes_ctr_crypt()
)调用函数ibuf
。
问题在于,对于每次调用,函数都需要记住上一次的两件事:
cbuf
)ctx
中并复制到局部变量b_pos
中的信息)。< / LI>
醇>
因此, b_pos
是密钥流模16中的位置。
换句话说,当函数完成某个数据的加密而不消耗最后一个计数器块中的所有16个字节时,它会为b_pos
留下值{{1}这样函数可以在下次调用时从那里继续。值0<b_pos<16
表示前一个计数器块中的所有字节都已用完,并且是时候调用计数器函数了。
关于0
,您应该将其读作:
b_pos < AES_BLOCK_SIZE && len
由于运营商优先权。循环终止要么是因为你用完了“剩余”密钥流字节(左手),要么是因为你用完了明文数据(右手)。