diff --git a/puer.c b/puer.c index 5b1845a..15b576c 100644 --- a/puer.c +++ b/puer.c @@ -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++) {