Make cc_{en,de}crypt stay within passed message length

This commit is contained in:
Juhani Krekelä 2021-04-09 20:36:27 +03:00
parent 4ec4a06776
commit 138cc5d2f5
1 changed files with 32 additions and 9 deletions

41
puer.c
View File

@ -305,6 +305,9 @@ void kdf(unsigned char key[16], unsigned char salt[32], unsigned char passphrase
// Use first 128 bits of final hash as the key
memcpy(key, final_hash, 16);
// Empty the buffer
explicit_bzero(workbuf, sizeof(workbuf));
}
// 16 bit authentication tag
@ -378,9 +381,6 @@ void ccm_xor_block(unsigned char block[16], uint32_t key[4], uint32_t messageind
}
}
// IMPORTANT: The underlying message[] must be addressable until the index
// ceil(length / 16)*16, but the length only reflects the actual message
// length
void ccm_encrypt(unsigned char key[16], uint32_t messageindex, unsigned char message[], uint32_t length, unsigned char mac[16]) {
uint32_t key_words[4];
block2words(key_words, key);
@ -391,14 +391,22 @@ void ccm_encrypt(unsigned char key[16], uint32_t messageindex, unsigned char mes
// Encrypt
// MAC is xored with first block of keystream
ccm_xor_block(mac, key_words, messageindex, 0);
// Xor the message
for (uint32_t index = 0; index < length; index += 16) {
// Xor full blocks
size_t index = 0;
for (; index + 16 <= length; index += 16) {
// Message blocks are numbered from index 1 onwards
ccm_xor_block(&message[index], key_words, messageindex, index + 1);
}
// Xor partial block, if any
if (index < length) {
unsigned char fullblock[16];
memcpy(fullblock, &message[index], length - index);
ccm_xor_block(fullblock, key_words, messageindex, index + 1);
memcpy(&message[index], fullblock, length - index);
}
}
// Same requirements for message[] hold as with ccm_encrypt
bool ccm_decrypt(unsigned char key[16], uint32_t messageindex, unsigned char message[], uint32_t length, unsigned char mac[16]) {
uint32_t key_words[4];
block2words(key_words, key);
@ -406,11 +414,20 @@ bool ccm_decrypt(unsigned char key[16], uint32_t messageindex, unsigned char mes
// Decrypt
// MAC is xored with first block of keystream
ccm_xor_block(mac, key_words, messageindex, 0);
// Xor the message
for (uint32_t index = 0; index < length; index += 16) {
// Xor full blocks
size_t index = 0;
for (; index + 16 <= length; index += 16) {
// Message blocks are numbered from index 1 onwards
ccm_xor_block(&message[index], key_words, messageindex, index + 1);
}
// Xor partial block, if any
if (index < length) {
unsigned char fullblock[16];
memcpy(fullblock, &message[index], length - index);
ccm_xor_block(fullblock, key_words, messageindex, index + 1);
memcpy(&message[index], fullblock, length - index);
}
// Compute the expected authentication tag
unsigned char computed_mac[16];
@ -526,8 +543,14 @@ int main(void) {
printf("\n\n");
char *message = "Syökää parsaa ja palvokaa saatanaa";
unsigned char buf[64] = {69};
unsigned char buf[64];
memset(buf, 0xab, sizeof(buf));
strcpy((char*)buf, message);
for (size_t i = 0; i < sizeof(buf); i++) {
printf("%02hhx ", buf[i]);
if (i % 16 == 15) printf("\n");
}
printf("\n");
ccm_encrypt(key, 25, buf, strlen(message), &buf[48]);
for (size_t i = 0; i < sizeof(buf); i++) {