Skip to content

Commit

Permalink
Extract pgp_cipher_encrypt_block to avoid duplicating pgp_cipher_cfb_…
Browse files Browse the repository at this point in the history
…encrypt/decrypt
  • Loading branch information
desvxx authored and ronaldtse committed May 2, 2024
1 parent 3b7b4fd commit e35e592
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 344 deletions.
164 changes: 2 additions & 162 deletions src/lib/crypto/symmetric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,170 +209,10 @@ pgp_cipher_cfb_finish(pgp_crypt_t *crypt)
return 0;
}

/* we rely on fact that in and out could be the same */
int
pgp_cipher_cfb_encrypt(pgp_crypt_t *crypt, uint8_t *out, const uint8_t *in, size_t bytes)
pgp_cipher_encrypt_block(pgp_crypt_t *crypt, uint8_t *iv, size_t blsize)
{
uint64_t *in64;
uint64_t buf64[512]; // 4KB - page size
uint64_t iv64[2];
size_t blocks, blockb;
size_t blsize = crypt->blocksize;

/* encrypting till the block boundary */
while (bytes && crypt->cfb.remaining) {
*out = *in++ ^ crypt->cfb.iv[blsize - crypt->cfb.remaining];
crypt->cfb.iv[blsize - crypt->cfb.remaining] = *out++;
crypt->cfb.remaining--;
bytes--;
}

if (!bytes) {
return 0;
}

/* encrypting full blocks */
if (bytes > blsize) {
memcpy(iv64, crypt->cfb.iv, blsize);
while ((blocks = bytes & ~(blsize - 1)) > 0) {
if (blocks > sizeof(buf64)) {
blocks = sizeof(buf64);
}
bytes -= blocks;
blockb = blocks;
memcpy(buf64, in, blockb);
in64 = buf64;

if (blsize == 16) {
blocks >>= 4;
while (blocks--) {
botan_block_cipher_encrypt_blocks(
crypt->cfb.obj, (uint8_t *) iv64, (uint8_t *) iv64, 1);
*in64 ^= iv64[0];
iv64[0] = *in64++;
*in64 ^= iv64[1];
iv64[1] = *in64++;
}
} else {
blocks >>= 3;
while (blocks--) {
botan_block_cipher_encrypt_blocks(
crypt->cfb.obj, (uint8_t *) iv64, (uint8_t *) iv64, 1);
*in64 ^= iv64[0];
iv64[0] = *in64++;
}
}

memcpy(out, buf64, blockb);
out += blockb;
in += blockb;
}

memcpy(crypt->cfb.iv, iv64, blsize);
}

if (!bytes) {
return 0;
}

botan_block_cipher_encrypt_blocks(crypt->cfb.obj, crypt->cfb.iv, crypt->cfb.iv, 1);
crypt->cfb.remaining = blsize;

/* encrypting tail */
while (bytes) {
*out = *in++ ^ crypt->cfb.iv[blsize - crypt->cfb.remaining];
crypt->cfb.iv[blsize - crypt->cfb.remaining] = *out++;
crypt->cfb.remaining--;
bytes--;
}

return 0;
}

/* we rely on fact that in and out could be the same */
int
pgp_cipher_cfb_decrypt(pgp_crypt_t *crypt, uint8_t *out, const uint8_t *in, size_t bytes)
{
/* for better code readability */
uint64_t *out64, *in64;
uint64_t inbuf64[512]; // 4KB - page size
uint64_t outbuf64[512];
uint64_t iv64[2];
size_t blocks, blockb;
size_t blsize = crypt->blocksize;

/* decrypting till the block boundary */
while (bytes && crypt->cfb.remaining) {
uint8_t c = *in++;
*out++ = c ^ crypt->cfb.iv[blsize - crypt->cfb.remaining];
crypt->cfb.iv[blsize - crypt->cfb.remaining] = c;
crypt->cfb.remaining--;
bytes--;
}

if (!bytes) {
return 0;
}

/* decrypting full blocks */
if (bytes > blsize) {
memcpy(iv64, crypt->cfb.iv, blsize);

while ((blocks = bytes & ~(blsize - 1)) > 0) {
if (blocks > sizeof(inbuf64)) {
blocks = sizeof(inbuf64);
}
bytes -= blocks;
blockb = blocks;
memcpy(inbuf64, in, blockb);
out64 = outbuf64;
in64 = inbuf64;

if (blsize == 16) {
blocks >>= 4;
while (blocks--) {
botan_block_cipher_encrypt_blocks(
crypt->cfb.obj, (uint8_t *) iv64, (uint8_t *) iv64, 1);
*out64++ = *in64 ^ iv64[0];
iv64[0] = *in64++;
*out64++ = *in64 ^ iv64[1];
iv64[1] = *in64++;
}
} else {
blocks >>= 3;
while (blocks--) {
botan_block_cipher_encrypt_blocks(
crypt->cfb.obj, (uint8_t *) iv64, (uint8_t *) iv64, 1);
*out64++ = *in64 ^ iv64[0];
iv64[0] = *in64++;
}
}

memcpy(out, outbuf64, blockb);
out += blockb;
in += blockb;
}

memcpy(crypt->cfb.iv, iv64, blsize);
}

if (!bytes) {
return 0;
}

botan_block_cipher_encrypt_blocks(crypt->cfb.obj, crypt->cfb.iv, crypt->cfb.iv, 1);
crypt->cfb.remaining = blsize;

/* decrypting tail */
while (bytes) {
uint8_t c = *in++;
*out++ = c ^ crypt->cfb.iv[blsize - crypt->cfb.remaining];
crypt->cfb.iv[blsize - crypt->cfb.remaining] = c;
crypt->cfb.remaining--;
bytes--;
}

return 0;
return botan_block_cipher_encrypt_blocks(crypt->cfb.obj, iv, iv, 1);
}

bool
Expand Down
2 changes: 2 additions & 0 deletions src/lib/crypto/symmetric.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ int pgp_cipher_cfb_decrypt(pgp_crypt_t *crypt, uint8_t *out, const uint8_t *in,

void pgp_cipher_cfb_resync(pgp_crypt_t *crypt, const uint8_t *buf);

int pgp_cipher_encrypt_block(pgp_crypt_t *crypt, uint8_t *iv, size_t blsize);

#if defined(ENABLE_AEAD)
/** @brief Initialize AEAD cipher instance
* @param crypt pgp crypto object
Expand Down
162 changes: 162 additions & 0 deletions src/lib/crypto/symmetric_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,168 @@ pgp_cipher_block_size(pgp_crypt_t *crypt)
return crypt->blocksize;
}

/* we rely on fact that in and out could be the same */
int
pgp_cipher_cfb_encrypt(pgp_crypt_t *crypt, uint8_t *out, const uint8_t *in, size_t bytes)
{
uint64_t *in64;
uint64_t buf64[512]; // 4KB - page size
uint64_t iv64[2];
size_t blocks, blockb;
size_t blsize = crypt->blocksize;

/* encrypting till the block boundary */
while (bytes && crypt->cfb.remaining) {
*out = *in++ ^ crypt->cfb.iv[blsize - crypt->cfb.remaining];
crypt->cfb.iv[blsize - crypt->cfb.remaining] = *out++;
crypt->cfb.remaining--;
bytes--;
}

if (!bytes) {
return 0;
}

/* encrypting full blocks */
if (bytes > blsize) {
memcpy(iv64, crypt->cfb.iv, blsize);
while ((blocks = bytes & ~(blsize - 1)) > 0) {
if (blocks > sizeof(buf64)) {
blocks = sizeof(buf64);
}
bytes -= blocks;
blockb = blocks;
memcpy(buf64, in, blockb);
in64 = buf64;

if (blsize == 16) {
blocks >>= 4;
while (blocks--) {
pgp_cipher_encrypt_block(crypt, (uint8_t *) iv64, 16);
*in64 ^= iv64[0];
iv64[0] = *in64++;
*in64 ^= iv64[1];
iv64[1] = *in64++;
}
} else {
blocks >>= 3;
while (blocks--) {
pgp_cipher_encrypt_block(crypt, (uint8_t *) iv64, 8);
*in64 ^= iv64[0];
iv64[0] = *in64++;
}
}

memcpy(out, buf64, blockb);
out += blockb;
in += blockb;
}

memcpy(crypt->cfb.iv, iv64, blsize);
}

if (!bytes) {
return 0;
}

pgp_cipher_encrypt_block(crypt, crypt->cfb.iv, blsize);
crypt->cfb.remaining = blsize;

/* encrypting tail */
while (bytes) {
*out = *in++ ^ crypt->cfb.iv[blsize - crypt->cfb.remaining];
crypt->cfb.iv[blsize - crypt->cfb.remaining] = *out++;
crypt->cfb.remaining--;
bytes--;
}

return 0;
}

/* we rely on fact that in and out could be the same */
int
pgp_cipher_cfb_decrypt(pgp_crypt_t *crypt, uint8_t *out, const uint8_t *in, size_t bytes)
{
/* for better code readability */
uint64_t *out64, *in64;
uint64_t inbuf64[512]; // 4KB - page size
uint64_t outbuf64[512];
uint64_t iv64[2];
size_t blocks, blockb;
size_t blsize = crypt->blocksize;

/* decrypting till the block boundary */
while (bytes && crypt->cfb.remaining) {
uint8_t c = *in++;
*out++ = c ^ crypt->cfb.iv[blsize - crypt->cfb.remaining];
crypt->cfb.iv[blsize - crypt->cfb.remaining] = c;
crypt->cfb.remaining--;
bytes--;
}

if (!bytes) {
return 0;
}

/* decrypting full blocks */
if (bytes > blsize) {
memcpy(iv64, crypt->cfb.iv, blsize);

while ((blocks = bytes & ~(blsize - 1)) > 0) {
if (blocks > sizeof(inbuf64)) {
blocks = sizeof(inbuf64);
}
bytes -= blocks;
blockb = blocks;
memcpy(inbuf64, in, blockb);
out64 = outbuf64;
in64 = inbuf64;

if (blsize == 16) {
blocks >>= 4;
while (blocks--) {
pgp_cipher_encrypt_block(crypt, (uint8_t *) iv64, 16);
*out64++ = *in64 ^ iv64[0];
iv64[0] = *in64++;
*out64++ = *in64 ^ iv64[1];
iv64[1] = *in64++;
}
} else {
blocks >>= 3;
while (blocks--) {
pgp_cipher_encrypt_block(crypt, (uint8_t *) iv64, 8);
*out64++ = *in64 ^ iv64[0];
iv64[0] = *in64++;
}
}

memcpy(out, outbuf64, blockb);
out += blockb;
in += blockb;
}

memcpy(crypt->cfb.iv, iv64, blsize);
}

if (!bytes) {
return 0;
}

pgp_cipher_encrypt_block(crypt, crypt->cfb.iv, blsize);
crypt->cfb.remaining = blsize;

/* decrypting tail */
while (bytes) {
uint8_t c = *in++;
*out++ = c ^ crypt->cfb.iv[blsize - crypt->cfb.remaining];
crypt->cfb.iv[blsize - crypt->cfb.remaining] = c;
crypt->cfb.remaining--;
bytes--;
}

return 0;
}

unsigned
pgp_block_size(pgp_symm_alg_t alg)
{
Expand Down
Loading

0 comments on commit e35e592

Please sign in to comment.