📄 aes_modes.c
字号:
if(op != obuf)
memcpy(obuf, buf, m * AES_BLOCK_SIZE);
ibuf += m * AES_BLOCK_SIZE;
obuf += m * AES_BLOCK_SIZE;
nb -= m;
}
}
if(iv != ivp)
memcpy(iv, ivp, AES_BLOCK_SIZE);
return EXIT_SUCCESS;
}
#endif
#if !defined( ASSUME_VIA_ACE_PRESENT )
# ifdef FAST_BUFFER_OPERATIONS
if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
while(nb--)
{
lp32(iv)[0] ^= lp32(ibuf)[0];
lp32(iv)[1] ^= lp32(ibuf)[1];
lp32(iv)[2] ^= lp32(ibuf)[2];
lp32(iv)[3] ^= lp32(ibuf)[3];
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
memcpy(obuf, iv, AES_BLOCK_SIZE);
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
}
else
# endif
while(nb--)
{
iv[ 0] ^= ibuf[ 0]; iv[ 1] ^= ibuf[ 1];
iv[ 2] ^= ibuf[ 2]; iv[ 3] ^= ibuf[ 3];
iv[ 4] ^= ibuf[ 4]; iv[ 5] ^= ibuf[ 5];
iv[ 6] ^= ibuf[ 6]; iv[ 7] ^= ibuf[ 7];
iv[ 8] ^= ibuf[ 8]; iv[ 9] ^= ibuf[ 9];
iv[10] ^= ibuf[10]; iv[11] ^= ibuf[11];
iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13];
iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15];
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
memcpy(obuf, iv, AES_BLOCK_SIZE);
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
}
#endif
return EXIT_SUCCESS;
}
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, const aes_decrypt_ctx ctx[1])
{ unsigned char tmp[AES_BLOCK_SIZE];
int nb = len >> 4;
if(len & (AES_BLOCK_SIZE - 1))
return EXIT_FAILURE;
#if defined( USE_VIA_ACE_IF_PRESENT )
if(ctx->inf.b[1] == 0xff)
{ uint_8t *ksp = kd_adr(ctx), *ivp = iv;
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
if(ALIGN_OFFSET( ctx, 16 ))
return EXIT_FAILURE;
if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */
{
ivp = liv;
memcpy(liv, iv, AES_BLOCK_SIZE);
}
if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 ))
{
via_cbc_op6(ksp,cwd,ibuf,obuf,nb,ivp);
}
else
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
uint_8t *ip, *op;
while(nb)
{
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : (uint_8t*)ibuf);
op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
if(ip != ibuf)
memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
via_cbc_op6(ksp,cwd,ip,op,m,ivp);
if(op != obuf)
memcpy(obuf, buf, m * AES_BLOCK_SIZE);
ibuf += m * AES_BLOCK_SIZE;
obuf += m * AES_BLOCK_SIZE;
nb -= m;
}
}
if(iv != ivp)
memcpy(iv, ivp, AES_BLOCK_SIZE);
return EXIT_SUCCESS;
}
#endif
#if !defined( ASSUME_VIA_ACE_PRESENT )
# ifdef FAST_BUFFER_OPERATIONS
if(!ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
while(nb--)
{
memcpy(tmp, ibuf, AES_BLOCK_SIZE);
if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
lp32(obuf)[0] ^= lp32(iv)[0];
lp32(obuf)[1] ^= lp32(iv)[1];
lp32(obuf)[2] ^= lp32(iv)[2];
lp32(obuf)[3] ^= lp32(iv)[3];
memcpy(iv, tmp, AES_BLOCK_SIZE);
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
}
else
# endif
while(nb--)
{
memcpy(tmp, ibuf, AES_BLOCK_SIZE);
if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1];
obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3];
obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5];
obuf[ 6] ^= iv[ 6]; obuf[ 7] ^= iv[ 7];
obuf[ 8] ^= iv[ 8]; obuf[ 9] ^= iv[ 9];
obuf[10] ^= iv[10]; obuf[11] ^= iv[11];
obuf[12] ^= iv[12]; obuf[13] ^= iv[13];
obuf[14] ^= iv[14]; obuf[15] ^= iv[15];
memcpy(iv, tmp, AES_BLOCK_SIZE);
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
}
#endif
return EXIT_SUCCESS;
}
AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, aes_encrypt_ctx ctx[1])
{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
if(b_pos) /* complete any partial block */
{
while(b_pos < AES_BLOCK_SIZE && cnt < len)
*obuf++ = iv[b_pos++] ^= *ibuf++, cnt++;
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
}
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */
{
#if defined( USE_VIA_ACE_IF_PRESENT )
if(ctx->inf.b[1] == 0xff)
{ int m;
uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
if(ALIGN_OFFSET( ctx, 16 ))
return EXIT_FAILURE;
if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */
{
ivp = liv;
memcpy(liv, iv, AES_BLOCK_SIZE);
}
if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
{
via_cfb_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);
ibuf += nb * AES_BLOCK_SIZE;
obuf += nb * AES_BLOCK_SIZE;
cnt += nb * AES_BLOCK_SIZE;
}
else /* input, output or both are unaligned */
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
uint_8t *ip, *op;
while(nb)
{
m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;
ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : (uint_8t*)ibuf);
op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
if(ip != ibuf)
memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
via_cfb_op7(ksp, cwd, ip, op, m, ivp, ivp);
if(op != obuf)
memcpy(obuf, buf, m * AES_BLOCK_SIZE);
ibuf += m * AES_BLOCK_SIZE;
obuf += m * AES_BLOCK_SIZE;
cnt += m * AES_BLOCK_SIZE;
}
}
if(ivp != iv)
memcpy(iv, ivp, AES_BLOCK_SIZE);
}
#else
# ifdef FAST_BUFFER_OPERATIONS
if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
while(cnt + AES_BLOCK_SIZE <= len)
{
assert(b_pos == 0);
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
lp32(obuf)[0] = lp32(iv)[0] ^= lp32(ibuf)[0];
lp32(obuf)[1] = lp32(iv)[1] ^= lp32(ibuf)[1];
lp32(obuf)[2] = lp32(iv)[2] ^= lp32(ibuf)[2];
lp32(obuf)[3] = lp32(iv)[3] ^= lp32(ibuf)[3];
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
cnt += AES_BLOCK_SIZE;
}
else
# endif
while(cnt + AES_BLOCK_SIZE <= len)
{
assert(b_pos == 0);
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
obuf[ 0] = iv[ 0] ^= ibuf[ 0]; obuf[ 1] = iv[ 1] ^= ibuf[ 1];
obuf[ 2] = iv[ 2] ^= ibuf[ 2]; obuf[ 3] = iv[ 3] ^= ibuf[ 3];
obuf[ 4] = iv[ 4] ^= ibuf[ 4]; obuf[ 5] = iv[ 5] ^= ibuf[ 5];
obuf[ 6] = iv[ 6] ^= ibuf[ 6]; obuf[ 7] = iv[ 7] ^= ibuf[ 7];
obuf[ 8] = iv[ 8] ^= ibuf[ 8]; obuf[ 9] = iv[ 9] ^= ibuf[ 9];
obuf[10] = iv[10] ^= ibuf[10]; obuf[11] = iv[11] ^= ibuf[11];
obuf[12] = iv[12] ^= ibuf[12]; obuf[13] = iv[13] ^= ibuf[13];
obuf[14] = iv[14] ^= ibuf[14]; obuf[15] = iv[15] ^= ibuf[15];
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
cnt += AES_BLOCK_SIZE;
}
#endif
}
while(cnt < len)
{
if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
return EXIT_FAILURE;
while(cnt < len && b_pos < AES_BLOCK_SIZE)
*obuf++ = iv[b_pos++] ^= *ibuf++, cnt++;
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
}
ctx->inf.b[2] = b_pos;
return EXIT_SUCCESS;
}
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, aes_encrypt_ctx ctx[1])
{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
if(b_pos) /* complete any partial block */
{ uint_8t t;
while(b_pos < AES_BLOCK_SIZE && cnt < len)
t = *ibuf++, *obuf++ = t ^ iv[b_pos], iv[b_pos++] = t, cnt++;
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
}
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */
{
#if defined( USE_VIA_ACE_IF_PRESENT )
if(ctx->inf.b[1] == 0xff)
{ int m;
uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
if(ALIGN_OFFSET( ctx, 16 ))
return EXIT_FAILURE;
if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */
{
ivp = liv;
memcpy(liv, iv, AES_BLOCK_SIZE);
}
if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
{
via_cfb_op6(ksp, cwd, ibuf, obuf, nb, ivp);
ibuf += nb * AES_BLOCK_SIZE;
obuf += nb * AES_BLOCK_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -