diff --git a/mkfiles/picipher_c.mk b/mkfiles/picipher_c.mk index 5da4e6c..2739819 100644 --- a/mkfiles/picipher_c.mk +++ b/mkfiles/picipher_c.mk @@ -6,7 +6,7 @@ AEAD_CIPHERS += $(ALGO_NAME) $(ALGO_NAME)_DIR := pi-cipher/ $(ALGO_NAME)_INCDIR := arcfour/ -$(ALGO_NAME)_OBJ := pi16cipher.o pi16cipher-asm.o pi32cipher.o pi64cipher.o +$(ALGO_NAME)_OBJ := pi16cipher.o pi16cipher-asm.o pi16cipher-aux-asm.o pi32cipher.o pi64cipher.o $(ALGO_NAME)_TESTBIN := main-picipher-test.o arcfour-asm.o $(CLI_STD) performance_test.o $(ALGO_NAME)_NESSIE_TEST := test nessie $(ALGO_NAME)_PERFORMANCE_TEST := performance diff --git a/pi-cipher/pi16cipher-asm.S b/pi-cipher/pi16cipher-asm.S index aabcb09..57bd4c0 100644 --- a/pi-cipher/pi16cipher-asm.S +++ b/pi-cipher/pi16cipher-asm.S @@ -1568,450 +1568,3 @@ pi16_decrypt_last_block: */ -/******************************************************************************/ -/* -void PI_ENCRYPT_SIMPLE( - void *cipher, - size_t *cipher_len_B, - void *tag, - size_t *tag_length_B, - const void *msg, - size_t msg_len_B, - const void *ad, - size_t ad_len_B, - const void *nonce_secret, - const void *nonce_public, - size_t nonce_public_len_B, - const void *key, - size_t key_len_B - ) -{ - unsigned i; - PI_CTX ctx; - if (PI_INIT(&ctx, key, key_len_B, nonce_public, nonce_public_len_B)) { - printf("ERROR! <%s %s %d>\n", __FILE__, __func__, __LINE__); - return; - } - i = 1; - while (ad_len_B >= PI_AD_BLOCK_LENGTH_BYTES) { - PI_PROCESS_AD_BLOCK(&ctx, ad, i++); - ad_len_B -= PI_AD_BLOCK_LENGTH_BYTES; - ad = &((const uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES]; - } - PI_PROCESS_AD_LAST_BLOCK(&ctx, ad, ad_len_B, i); - *cipher_len_B = 0; - if (nonce_secret) { - PI_PROCESS_SMN(&ctx, cipher, nonce_secret); - *cipher_len_B += PI_CT_BLOCK_LENGTH_BYTES; - cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES]; - } - i = 1; - while (msg_len_B >= PI_PT_BLOCK_LENGTH_BYTES) { - PI_ENCRYPT_BLOCK(&ctx, cipher, msg, i++); - msg = &((const uint8_t*)msg)[PI_PT_BLOCK_LENGTH_BYTES]; - cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES]; - *cipher_len_B += PI_CT_BLOCK_LENGTH_BYTES; - msg_len_B -= PI_PT_BLOCK_LENGTH_BYTES; - } - PI_ENCRYPT_LAST_BLOCK(&ctx, cipher, msg, msg_len_B, i); - *cipher_len_B += msg_len_B; - PI_EXTRACT_TAG(&ctx, tag); - if (tag_length_B) { - *tag_length_B = PI_TAG_BYTES; - } -} -*/ -/* - void *cipher, -- r24:r25 -- Y[16] - size_t *cipher_len_B, -- r22:r23 -- Y[14] - const void *msg, -- r20:r21 -- Y[12] - size_t msg_len_B, -- r18:r19 -- Y[10] - const void *ad, -- r16:r17 -- Y[ 8] - size_t ad_len_B, -- r14:r15 -- Y[ 6] - const void *nonce_secret, -- r12:r13 -- Y[ 4] - const void *nonce_public, -- r10:r11 -- Y[ 2] - size_t nonce_public_len_B, -- r8: r9 -- Y[ 0] - const void *key, -- SP[2] -- Y[22] - size_t key_len_B -- SP[4] -- Y[24] -*/ -.equ cipher, 16 -.equ cipher_len_B, 14 -.equ msg, 12 -.equ msg_len_B, 10 -.equ ad, 8 -.equ ad_len_B, 6 -.equ nonce_secret, 4 -.equ nonce_public, 2 -.equ nonce_public_len_B, 0 -.equ key, 22 -.equ key_len_B, 24 - -.global pi16_encrypt_simple -pi16_encrypt_simple: - push r28 - push r29 - stack_alloc_large ctx_size + 9 * 2, reg1 = r30, reg2 = r31 - adiw r30, 1 + ctx_size - ldi r26, 18 - clr r29 - ldi r28, 8 - -1: - ld r0, Y+ - st Z+, r0 - dec r26 - brne 1b - sbiw r30, 18 - movw r28, r30 ; Y points at var backup - sbiw r30, ctx_size ; Z points at ctx - movw r8, r30 - - movw r24, r8 - ldd r22, Y + key ; load key - ldd r23, Y + key + 1 ; - ldd r20, Y + key_len_B ; load key_len_B - ldd r21, Y + key_len_B + 1 ; - ldd r18, Y + nonce_public ; load nonce_public - ldd r19, Y + nonce_public + 1 ; - ldd r16, Y + nonce_public_len_B ; load nonce_public_len_B - ldd r17, Y + nonce_public_len_B + 1 ; - rcall pi16_init - or r25, 24 - brne encrypt_simple_init_fault - - movw r24, r8 - ldd r22, Y + ad ; load ad - ldd r23, Y + ad + 1 ; - ldd r20, Y + ad_len_B ; ad_len_B - ldd r21, Y + ad_len_B + 1 ; - clr r18 - clr r19 - ldi r16, 1 ; set num = 1 - clr r17 - rcall pi16_process_ad_last_block - - ldd r26, Y + cipher_len_B ; load cipher_len_B - ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B - ldi r16, 16 - st X+, r16 - st X+, r1 ; set cipher_len_B = 0 - ldd r10, Y + cipher ; load *cipher - ldd r11, Y + cipher + 1 - movw r24, r10 - - ldd r20, Y + nonce_secret ; load smn - ldd r21, Y + nonce_secret + 1 - cp r20, r1 - cpc r21, r1 - breq 2f - - sbiw r26, 2 - ldi r16, 32 - st X+, r16 ; store "incermented" cipher counter - movw r22, r10 - movw r24, r8 - rcall pi16_encrypt_smn - movw r24, r10 - adiw r24, 16 -2: - movw r22, r24 - movw r24, r8 - ldd r18, Y + msg_len_B ; load msg_len_B - ldd r19, Y + msg_len_B + 1 ; - ldd r20, Y + msg ; load msg - ldd r21, Y + msg + 1 ; - ldd r26, Y + cipher_len_B ; load cipher_len_B - ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B - ld r16, X - add r16, r18 - st X+, r16 - ld r17, X - adc r17, r19 - st X+, r17 - movw r12, r22 - add r12, r18 - adc r13, r19 - clr r17 - clr r16 - clr r15 - clr r14 - inc r14 ; set num = 1 - rcall pi16_encrypt_last_block - - movw r24, r8 - movw r22, r12 - rcall pi16_extract_tag - - rjmp 1f -; Y must point at var backup! -encrypt_simple_init_fault: - ldd r26, Y + cipher_len_B ; load cipher_len_B - ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B - st X+, r1 - st X+, r1 - -1: - ldi r26, 18 - clr r31 - ldi r30, 8 - -1: - ld r0, Y+ - st Z+, r0 - dec r26 - brne 1b - - stack_free_large ctx_size + 9 * 2 - pop r29 - pop r28 - ret - - -/******************************************************************************/ -/* -int PI_DECRYPT_SIMPLE( - void *msg, - size_t *msg_len_B, - void *nonce_secret, - const void *cipher, - size_t cipher_len_B, - const void *ad, - size_t ad_len_B, - const void *nonce_public, - size_t nonce_public_len_B, - const void *key, - size_t key_len_B - ) -{ - unsigned i; - PI_CTX ctx; - - unsigned long clen = cipher_len_B, alen = ad_len_B; - uint8_t bck_c[clen], bck_ad[alen]; - memcpy(bck_c, cipher, clen); - memcpy(bck_ad, ad, alen); - - uint8_t tmp_tag[PI_TAG_BYTES]; - if (nonce_secret && (cipher_len_B < PI_CT_BLOCK_LENGTH_BYTES + PI_TAG_BYTES)) { - return -3; - } - if (PI_INIT(&ctx, key, key_len_B, nonce_public, nonce_public_len_B)) { - printf("ERROR! <%s %s %d>\n", __FILE__, __func__, __LINE__); - return -2; - } - i = 1; - while (ad_len_B >= PI_AD_BLOCK_LENGTH_BYTES) { - PI_PROCESS_AD_BLOCK(&ctx, ad, i++); - ad_len_B -= PI_AD_BLOCK_LENGTH_BYTES; - ad = &((const uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES]; - } - PI_PROCESS_AD_LAST_BLOCK(&ctx, ad, ad_len_B, i); - *msg_len_B = 0; - if (nonce_secret) { - PI_DECRYPT_SMN(&ctx, nonce_secret, cipher); - cipher_len_B -= PI_CT_BLOCK_LENGTH_BYTES; - cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES]; - } - i = 1; - while (cipher_len_B - PI_TAG_BYTES >= PI_PT_BLOCK_LENGTH_BYTES) { - PI_DECRYPT_BLOCK(&ctx, msg, cipher, i++); - msg = &((uint8_t*)msg)[PI_PT_BLOCK_LENGTH_BYTES]; - cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES]; - cipher_len_B -= PI_CT_BLOCK_LENGTH_BYTES; - *msg_len_B += PI_PT_BLOCK_LENGTH_BYTES; - } - PI_DECRYPT_LAST_BLOCK(&ctx, msg, cipher, cipher_len_B - PI_TAG_BYTES, i); - *msg_len_B += cipher_len_B - PI_TAG_BYTES; - cipher = &((uint8_t*)cipher)[cipher_len_B - PI_TAG_BYTES]; - PI_EXTRACT_TAG(&ctx, tmp_tag); - if (memcmp(tmp_tag, cipher, PI_TAG_BYTES)) { -#if DEBUG - printf("DBG: verification failed: clen = %lu; alen = %lu\n", clen, alen); - printf("Key:\n"); - hexdump_block(key, key_len_B, 4, 16); - printf("\nNonce:\n"); - hexdump_block(nonce_public, nonce_public_len_B, 4, 16); - printf("\nAD:\n"); - hexdump_block(bck_ad, alen, 4, 16); - printf("\nCiphertext:\n"); - hexdump_block(bck_c, clen, 4, 16); - printf("\nShould-Tag:\n"); - hexdump_block(cipher, PI_TAG_BYTES, 4, 16); - printf("\nIS-Tag:\n"); - hexdump_block(tmp_tag, PI_TAG_BYTES, 4, 16); - puts(""); -#endif - return -1; - } - return 0; -} -*/ - -/* - void *msg, -- r24:r25 -- Y[16] - size_t *msg_len_B, -- r22:r23 -- Y[14] - void *nonce_secret, -- r20:r21 -- Y[12] - const void *cipher, -- r18:r19 -- Y[10] - size_t cipher_len_B, -- r16:r17 -- Y[ 8] - const void *ad, -- r14:r15 -- Y[ 6] - size_t ad_len_B, -- r12:r13 -- Y[ 4] - const void *nonce_public, -- r10:r11 -- Y[ 2] - size_t nonce_public_len_B, -- r8: r9 -- Y[ 0] - const void *key, -- SP[2] -- Y[22] - size_t key_len_B -- SP[4] -- Y[24] -*/ -.equ msg, 16 -.equ msg_len_B, 14 -.equ nonce_secret, 12 -.equ cipher, 10 -.equ cipher_len_B, 8 -.equ ad, 6 -.equ ad_len_B, 4 -.equ nonce_public, 2 -.equ nonce_public_len_B, 0 -.equ key, 22 -.equ key_len_B, 24 - -.global pi16_decrypt_simple -pi16_decrypt_simple: - push r28 - push r29 - stack_alloc_large ctx_size + 9 * 2, reg1 = r30, reg2 = r31 - adiw r30, 1 + ctx_size - ldi r26, 18 - clr r29 - ldi r28, 8 - -1: - ld r0, Y+ - st Z+, r0 - dec r26 - brne 1b - sbiw r30, 18 - movw r28, r30 ; Y points at var backup - sbiw r30, ctx_size ; Z points at ctx - movw r8, r30 - - movw r24, r8 - ldd r22, Y + key ; load key - ldd r23, Y + key + 1 ; - ldd r20, Y + key_len_B ; load key_len_B - ldd r21, Y + key_len_B + 1 ; - ldd r18, Y + nonce_public ; load nonce_public - ldd r19, Y + nonce_public + 1 ; - ldd r16, Y + nonce_public_len_B ; load nonce_public_len_B - ldd r17, Y + nonce_public_len_B + 1 ; - rcall pi16_init - or r25, 24 - breq 1f - rjmp decrypt_simple_init_fault -1: - - movw r24, r8 - ldd r22, Y + ad ; load ad - ldd r23, Y + ad + 1 ; - ldd r20, Y + ad_len_B ; ad_len_B - ldd r21, Y + ad_len_B + 1 ; - ldi r16, 1 ; set num = 1 - clr r17 - clr r18 - clr r19 - rcall pi16_process_ad_last_block - - ldd r26, Y + cipher_len_B ; load cipher_len_B - ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B - ldd r10, Y + cipher ; load *cipher - ldd r11, Y + cipher + 1 - movw r24, r10 - ldd r22, Y + nonce_secret ; load smn - ldd r23, Y + nonce_secret + 1 - cp r22, r1 - cpc r23, r1 - breq 2f - - movw r20, r10 - movw r24, r8 - rcall pi16_decrypt_smn - movw r24, r10 - adiw r24, 16 - ldd r26, Y + cipher_len_B ; load cipher_len_B - ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B - sbiw r26, 16 -2: - sbiw r26, 16 ; subtract 16 for tag - movw r20, r24 ; transfer cipher - movw r24, r8 - movw r18, r26 - ldd r22, Y + msg ; load msg - ldd r23, Y + msg + 1 ; - ldd r26, Y + msg_len_B ; load msg_len_B - ldd r27, Y + msg_len_B + 1 ; load msg_len_B - st X+, r18 - st X+, r19 - movw r12, r20 - add r12, r18 - adc r13, r19 - clr r17 - clr r16 - clr r15 - clr r14 - inc r14 ; set num = 1 - rcall pi16_decrypt_last_block - - ldi r24, 16 - movw r30, r12 - sbiw r28, ctx_size - ctx_tag - clr r25 -1: - ld r0, Z+ - ld r16, Y+ - eor r0, r16 - or r25, r0 - dec r24 - brne 1b - - adiw r28, ctx_size - ctx_ctr - - tst r25 - brne 1f - push r1 - push r1 - rjmp 2f -1: - ser r24 - ser r25 -; Y must point at var backup! - rjmp 1f -decrypt_simple_init_fault: - ldd r26, Y + msg_len_B ; load cipher_len_B - ldd r27, Y + msg_len_B ; load cipher_len_B - st X+, r1 - st X+, r1 - ser r24 - ser r25 - sbiw r24, 1 -1: - push r24 - push r25 -2: - ldi r26, 18 - clr r31 - ldi r30, 8 - -1: - ld r0, Y+ - st Z+, r0 - dec r26 - brne 1b - - pop r25 - pop r24 - stack_free_large ctx_size + 9 * 2 - pop r29 - pop r28 - ret - - - - - diff --git a/pi-cipher/pi16cipher-aux-asm.S b/pi-cipher/pi16cipher-aux-asm.S new file mode 100644 index 0000000..17a34fd --- /dev/null +++ b/pi-cipher/pi16cipher-aux-asm.S @@ -0,0 +1,478 @@ +/* pi16cipher-asm.S */ +/* + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2015 Daniel Otte (bg@nerilex.org) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include "avr-asm-macros.S" + + .struct 0 +ctx: +ctx_state: + .struct ctx_state + 4 * 4 * 2 +ctx_tag: + .struct ctx_tag + 4 * 2 * 2 +ctx_ctr: + .struct ctx_ctr + 8 +ctx_end: +ctx_size: + +.text + +/******************************************************************************/ +/* +void PI_ENCRYPT_SIMPLE( + void *cipher, + size_t *cipher_len_B, + void *tag, + size_t *tag_length_B, + const void *msg, + size_t msg_len_B, + const void *ad, + size_t ad_len_B, + const void *nonce_secret, + const void *nonce_public, + size_t nonce_public_len_B, + const void *key, + size_t key_len_B + ) +{ + unsigned i; + PI_CTX ctx; + if (PI_INIT(&ctx, key, key_len_B, nonce_public, nonce_public_len_B)) { + printf("ERROR! <%s %s %d>\n", __FILE__, __func__, __LINE__); + return; + } + i = 1; + while (ad_len_B >= PI_AD_BLOCK_LENGTH_BYTES) { + PI_PROCESS_AD_BLOCK(&ctx, ad, i++); + ad_len_B -= PI_AD_BLOCK_LENGTH_BYTES; + ad = &((const uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES]; + } + PI_PROCESS_AD_LAST_BLOCK(&ctx, ad, ad_len_B, i); + *cipher_len_B = 0; + if (nonce_secret) { + PI_PROCESS_SMN(&ctx, cipher, nonce_secret); + *cipher_len_B += PI_CT_BLOCK_LENGTH_BYTES; + cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES]; + } + i = 1; + while (msg_len_B >= PI_PT_BLOCK_LENGTH_BYTES) { + PI_ENCRYPT_BLOCK(&ctx, cipher, msg, i++); + msg = &((const uint8_t*)msg)[PI_PT_BLOCK_LENGTH_BYTES]; + cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES]; + *cipher_len_B += PI_CT_BLOCK_LENGTH_BYTES; + msg_len_B -= PI_PT_BLOCK_LENGTH_BYTES; + } + PI_ENCRYPT_LAST_BLOCK(&ctx, cipher, msg, msg_len_B, i); + *cipher_len_B += msg_len_B; + PI_EXTRACT_TAG(&ctx, tag); + if (tag_length_B) { + *tag_length_B = PI_TAG_BYTES; + } +} +*/ +/* + void *cipher, -- r24:r25 -- Y[16] + size_t *cipher_len_B, -- r22:r23 -- Y[14] + const void *msg, -- r20:r21 -- Y[12] + size_t msg_len_B, -- r18:r19 -- Y[10] + const void *ad, -- r16:r17 -- Y[ 8] + size_t ad_len_B, -- r14:r15 -- Y[ 6] + const void *nonce_secret, -- r12:r13 -- Y[ 4] + const void *nonce_public, -- r10:r11 -- Y[ 2] + size_t nonce_public_len_B, -- r8: r9 -- Y[ 0] + const void *key, -- SP[2] -- Y[22] + size_t key_len_B -- SP[4] -- Y[24] +*/ +.equ cipher, 16 +.equ cipher_len_B, 14 +.equ msg, 12 +.equ msg_len_B, 10 +.equ ad, 8 +.equ ad_len_B, 6 +.equ nonce_secret, 4 +.equ nonce_public, 2 +.equ nonce_public_len_B, 0 +.equ key, 22 +.equ key_len_B, 24 + +.global pi16_encrypt_simple +pi16_encrypt_simple: + push r28 + push r29 + stack_alloc_large ctx_size + 9 * 2, reg1 = r30, reg2 = r31 + adiw r30, 1 + ctx_size + ldi r26, 18 + clr r29 + ldi r28, 8 + +1: + ld r0, Y+ + st Z+, r0 + dec r26 + brne 1b + sbiw r30, 18 + movw r28, r30 ; Y points at var backup + sbiw r30, ctx_size ; Z points at ctx + movw r8, r30 + + movw r24, r8 + ldd r22, Y + key ; load key + ldd r23, Y + key + 1 ; + ldd r20, Y + key_len_B ; load key_len_B + ldd r21, Y + key_len_B + 1 ; + ldd r18, Y + nonce_public ; load nonce_public + ldd r19, Y + nonce_public + 1 ; + ldd r16, Y + nonce_public_len_B ; load nonce_public_len_B + ldd r17, Y + nonce_public_len_B + 1 ; + rcall pi16_init + or r25, 24 + brne encrypt_simple_init_fault + + movw r24, r8 + ldd r22, Y + ad ; load ad + ldd r23, Y + ad + 1 ; + ldd r20, Y + ad_len_B ; ad_len_B + ldd r21, Y + ad_len_B + 1 ; + clr r18 + clr r19 + ldi r16, 1 ; set num = 1 + clr r17 + rcall pi16_process_ad_last_block + + ldd r26, Y + cipher_len_B ; load cipher_len_B + ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B + ldi r16, 16 + st X+, r16 + st X+, r1 ; set cipher_len_B = 0 + ldd r10, Y + cipher ; load *cipher + ldd r11, Y + cipher + 1 + movw r24, r10 + + ldd r20, Y + nonce_secret ; load smn + ldd r21, Y + nonce_secret + 1 + cp r20, r1 + cpc r21, r1 + breq 2f + + sbiw r26, 2 + ldi r16, 32 + st X+, r16 ; store "incermented" cipher counter + movw r22, r10 + movw r24, r8 + rcall pi16_encrypt_smn + movw r24, r10 + adiw r24, 16 +2: + movw r22, r24 + movw r24, r8 + ldd r18, Y + msg_len_B ; load msg_len_B + ldd r19, Y + msg_len_B + 1 ; + ldd r20, Y + msg ; load msg + ldd r21, Y + msg + 1 ; + ldd r26, Y + cipher_len_B ; load cipher_len_B + ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B + ld r16, X + add r16, r18 + st X+, r16 + ld r17, X + adc r17, r19 + st X+, r17 + movw r12, r22 + add r12, r18 + adc r13, r19 + clr r17 + clr r16 + clr r15 + clr r14 + inc r14 ; set num = 1 + rcall pi16_encrypt_last_block + + movw r24, r8 + movw r22, r12 + rcall pi16_extract_tag + + rjmp 1f +; Y must point at var backup! +encrypt_simple_init_fault: + ldd r26, Y + cipher_len_B ; load cipher_len_B + ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B + st X+, r1 + st X+, r1 + +1: + ldi r26, 18 + clr r31 + ldi r30, 8 + +1: + ld r0, Y+ + st Z+, r0 + dec r26 + brne 1b + + stack_free_large ctx_size + 9 * 2 + pop r29 + pop r28 + ret + + +/******************************************************************************/ +/* +int PI_DECRYPT_SIMPLE( + void *msg, + size_t *msg_len_B, + void *nonce_secret, + const void *cipher, + size_t cipher_len_B, + const void *ad, + size_t ad_len_B, + const void *nonce_public, + size_t nonce_public_len_B, + const void *key, + size_t key_len_B + ) +{ + unsigned i; + PI_CTX ctx; + + unsigned long clen = cipher_len_B, alen = ad_len_B; + uint8_t bck_c[clen], bck_ad[alen]; + memcpy(bck_c, cipher, clen); + memcpy(bck_ad, ad, alen); + + uint8_t tmp_tag[PI_TAG_BYTES]; + if (nonce_secret && (cipher_len_B < PI_CT_BLOCK_LENGTH_BYTES + PI_TAG_BYTES)) { + return -3; + } + if (PI_INIT(&ctx, key, key_len_B, nonce_public, nonce_public_len_B)) { + printf("ERROR! <%s %s %d>\n", __FILE__, __func__, __LINE__); + return -2; + } + i = 1; + while (ad_len_B >= PI_AD_BLOCK_LENGTH_BYTES) { + PI_PROCESS_AD_BLOCK(&ctx, ad, i++); + ad_len_B -= PI_AD_BLOCK_LENGTH_BYTES; + ad = &((const uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES]; + } + PI_PROCESS_AD_LAST_BLOCK(&ctx, ad, ad_len_B, i); + *msg_len_B = 0; + if (nonce_secret) { + PI_DECRYPT_SMN(&ctx, nonce_secret, cipher); + cipher_len_B -= PI_CT_BLOCK_LENGTH_BYTES; + cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES]; + } + i = 1; + while (cipher_len_B - PI_TAG_BYTES >= PI_PT_BLOCK_LENGTH_BYTES) { + PI_DECRYPT_BLOCK(&ctx, msg, cipher, i++); + msg = &((uint8_t*)msg)[PI_PT_BLOCK_LENGTH_BYTES]; + cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES]; + cipher_len_B -= PI_CT_BLOCK_LENGTH_BYTES; + *msg_len_B += PI_PT_BLOCK_LENGTH_BYTES; + } + PI_DECRYPT_LAST_BLOCK(&ctx, msg, cipher, cipher_len_B - PI_TAG_BYTES, i); + *msg_len_B += cipher_len_B - PI_TAG_BYTES; + cipher = &((uint8_t*)cipher)[cipher_len_B - PI_TAG_BYTES]; + PI_EXTRACT_TAG(&ctx, tmp_tag); + if (memcmp(tmp_tag, cipher, PI_TAG_BYTES)) { +#if DEBUG + printf("DBG: verification failed: clen = %lu; alen = %lu\n", clen, alen); + printf("Key:\n"); + hexdump_block(key, key_len_B, 4, 16); + printf("\nNonce:\n"); + hexdump_block(nonce_public, nonce_public_len_B, 4, 16); + printf("\nAD:\n"); + hexdump_block(bck_ad, alen, 4, 16); + printf("\nCiphertext:\n"); + hexdump_block(bck_c, clen, 4, 16); + printf("\nShould-Tag:\n"); + hexdump_block(cipher, PI_TAG_BYTES, 4, 16); + printf("\nIS-Tag:\n"); + hexdump_block(tmp_tag, PI_TAG_BYTES, 4, 16); + puts(""); +#endif + return -1; + } + return 0; +} +*/ + +/* + void *msg, -- r24:r25 -- Y[16] + size_t *msg_len_B, -- r22:r23 -- Y[14] + void *nonce_secret, -- r20:r21 -- Y[12] + const void *cipher, -- r18:r19 -- Y[10] + size_t cipher_len_B, -- r16:r17 -- Y[ 8] + const void *ad, -- r14:r15 -- Y[ 6] + size_t ad_len_B, -- r12:r13 -- Y[ 4] + const void *nonce_public, -- r10:r11 -- Y[ 2] + size_t nonce_public_len_B, -- r8: r9 -- Y[ 0] + const void *key, -- SP[2] -- Y[22] + size_t key_len_B -- SP[4] -- Y[24] +*/ +.equ msg, 16 +.equ msg_len_B, 14 +.equ nonce_secret, 12 +.equ cipher, 10 +.equ cipher_len_B, 8 +.equ ad, 6 +.equ ad_len_B, 4 +.equ nonce_public, 2 +.equ nonce_public_len_B, 0 +.equ key, 22 +.equ key_len_B, 24 + +.global pi16_decrypt_simple +pi16_decrypt_simple: + push r28 + push r29 + stack_alloc_large ctx_size + 9 * 2, reg1 = r30, reg2 = r31 + adiw r30, 1 + ctx_size + ldi r26, 18 + clr r29 + ldi r28, 8 + +1: + ld r0, Y+ + st Z+, r0 + dec r26 + brne 1b + sbiw r30, 18 + movw r28, r30 ; Y points at var backup + sbiw r30, ctx_size ; Z points at ctx + movw r8, r30 + + movw r24, r8 + ldd r22, Y + key ; load key + ldd r23, Y + key + 1 ; + ldd r20, Y + key_len_B ; load key_len_B + ldd r21, Y + key_len_B + 1 ; + ldd r18, Y + nonce_public ; load nonce_public + ldd r19, Y + nonce_public + 1 ; + ldd r16, Y + nonce_public_len_B ; load nonce_public_len_B + ldd r17, Y + nonce_public_len_B + 1 ; + rcall pi16_init + or r25, 24 + breq 1f + rjmp decrypt_simple_init_fault +1: + + movw r24, r8 + ldd r22, Y + ad ; load ad + ldd r23, Y + ad + 1 ; + ldd r20, Y + ad_len_B ; ad_len_B + ldd r21, Y + ad_len_B + 1 ; + ldi r16, 1 ; set num = 1 + clr r17 + clr r18 + clr r19 + rcall pi16_process_ad_last_block + + ldd r26, Y + cipher_len_B ; load cipher_len_B + ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B + ldd r10, Y + cipher ; load *cipher + ldd r11, Y + cipher + 1 + movw r24, r10 + ldd r22, Y + nonce_secret ; load smn + ldd r23, Y + nonce_secret + 1 + cp r22, r1 + cpc r23, r1 + breq 2f + + movw r20, r10 + movw r24, r8 + rcall pi16_decrypt_smn + movw r24, r10 + adiw r24, 16 + ldd r26, Y + cipher_len_B ; load cipher_len_B + ldd r27, Y + cipher_len_B + 1 ; load cipher_len_B + sbiw r26, 16 +2: + sbiw r26, 16 ; subtract 16 for tag + movw r20, r24 ; transfer cipher + movw r24, r8 + movw r18, r26 + ldd r22, Y + msg ; load msg + ldd r23, Y + msg + 1 ; + ldd r26, Y + msg_len_B ; load msg_len_B + ldd r27, Y + msg_len_B + 1 ; load msg_len_B + st X+, r18 + st X+, r19 + movw r12, r20 + add r12, r18 + adc r13, r19 + clr r17 + clr r16 + clr r15 + clr r14 + inc r14 ; set num = 1 + rcall pi16_decrypt_last_block + + ldi r24, 16 + movw r30, r12 + sbiw r28, ctx_size - ctx_tag + clr r25 +1: + ld r0, Z+ + ld r16, Y+ + eor r0, r16 + or r25, r0 + dec r24 + brne 1b + + adiw r28, ctx_size - ctx_ctr + + tst r25 + brne 1f + push r1 + push r1 + rjmp 2f +1: + ser r24 + ser r25 +; Y must point at var backup! + rjmp 1f +decrypt_simple_init_fault: + ldd r26, Y + msg_len_B ; load cipher_len_B + ldd r27, Y + msg_len_B ; load cipher_len_B + st X+, r1 + st X+, r1 + ser r24 + ser r25 + sbiw r24, 1 +1: + push r24 + push r25 +2: + ldi r26, 18 + clr r31 + ldi r30, 8 + +1: + ld r0, Y+ + st Z+, r0 + dec r26 + brne 1b + + pop r25 + pop r24 + stack_free_large ctx_size + 9 * 2 + pop r29 + pop r28 + ret +