#include"auxFormat.h" #define RATE (64 / 8) #define PR0_ROUNDS 52 #define PR_ROUNDS 28 #define PRF_ROUNDS 32 unsigned char constant6Format[63] = { /*constant6_aead_128v1:*/ 0x1, 0x10, 0x2, 0x20, 0x4, 0x41, 0x11, 0x12, 0x22, 0x24, 0x45, 0x50, 0x3, 0x30, 0x6, 0x61, 0x15, 0x53, 0x33, 0x36, 0x67, 0x74, 0x46, 0x60, 0x5, 0x51, 0x13, 0x32, 0x26, 0x65, 0x54, 0x42, 0x21, 0x14, 0x43, 0x31, 0x16, 0x63, 0x35, 0x57, 0x72, 0x27, 0x75, 0x56, 0x62, 0x25, 0x55, 0x52, 0x23, 0x34, 0x47, 0x70, 0x7, 0x71, 0x17, 0x73, 0x37, 0x77, 0x76, 0x66, 0x64, 0x44, 0x40, }; static void permutation256(unsigned int *in, int rounds, unsigned char *rc) { uint32_t w0, w1, w2, w3, w4, w5, w6, w7; uint32_t s0, s1, s2; __asm volatile( "ldr %[w0], [%[in]] \n\t" "ldr %[w4], [%[in], #4] \n\t" "ldr %[w1], [%[in], #8] \n\t" "ldr %[w5], [%[in], #12] \n\t" "ldr %[w2], [%[in], #16] \n\t" "ldr %[w6], [%[in], #20] \n\t" "ldr %[w3], [%[in], #24] \n\t" "ldr %[w7], [%[in], #28] \n\t" "enc_loop_%=: \n\t" "/*add round const s0 s1*/ \n\t" "ldrb %[s0], [%[rc]] \n\t" "LSR %[s1], %[s0], #4 \n\t" "and %[s0], %[s0], 0xf \n\t" "eors %[w4], %[w4], %[s0] \n\t" "eors %[w0], %[w0], %[s1] \n\t" "/*sbox first column*/ \n\t" "mvns %[w0], %[w0] \n\t" "ands %[s0], %[w1], %[w0] \n\t" "eors %[s0], %[w2], %[s0] \n\t" "orrs %[w2], %[w1], %[w2] \n\t" "eors %[w0], %[w3], %[w0] \n\t" "eors %[w2], %[w2], %[w0] \n\t" "eors %[s1], %[w1], %[w3] \n\t" "eors %[w3], %[w3], %[s0] \n\t" "ands %[w0], %[s0], %[w0] \n\t" "eors %[w0], %[s1], %[w0] \n\t" "ands %[w1], %[w2], %[s1] \n\t" "eors %[w1], %[s0], %[w1] \n\t" "/*sbox second column*/ \n\t" "mvns %[w4], %[w4] \n\t" "ands %[s0], %[w5], %[w4] \n\t" "eors %[s0], %[w6], %[s0] \n\t" "orrs %[w6], %[w5], %[w6] \n\t" "eors %[w4], %[w7], %[w4] \n\t" "eors %[w6], %[w6], %[w4] \n\t" "eors %[s1], %[w5], %[w7] \n\t" "eors %[w7], %[w7], %[s0] \n\t" "ands %[w4], %[s0], %[w4] \n\t" "eors %[w4], %[s1], %[w4] \n\t" "ands %[w5], %[w6], %[s1] \n\t" "eors %[w5], %[s0], %[w5] \n\t" "/*rotate shift left 1 bit*/ \n\t" "mov %[s0], %[w5] \n\t" "ROR %[w5], %[w1], #31 \n\t" "mov %[w1], %[s0] \n\t" "/*rotate shift left 8 bits*/ \n\t" "ROR %[w2], %[w2], #28 \n\t" "ROR %[w6], %[w6], #28 \n\t" "/*rotate shift left 25 bits*/ \n\t" "mov %[s0], %[w3] \n\t" "ROR %[w3], %[w7], #20 \n\t" "ROR %[w7], %[s0], #19 \n\t" "/*loop control*/ \n\t" "adds %[rc], %[rc], #1 \n\t" "subs %[rounds], %[rounds], #1 \n\t" "bne enc_loop_%= \n\t" "str %[w0], [%[in]] \n\t" "str %[w4], [%[in], #4] \n\t" "str %[w1], [%[in], #8] \n\t" "str %[w5], [%[in], #12] \n\t" "str %[w2], [%[in], #16] \n\t" "str %[w6], [%[in], #20] \n\t" "str %[w3], [%[in], #24] \n\t" "str %[w7], [%[in], #28] \n\t" : [rounds] "=r" (rounds), [rc] "=r" (rc), [w0] "=r" (w0), [w1] "=r" (w1), [w2] "=r" (w2), [w3] "=r" (w3), [w4] "=r" (w4), [w5] "=r" (w5), [w6] "=r" (w6), [w7] "=r" (w7), [s0] "=r" (s0), [s1] "=r" (s1), [s2] "=r" (s2) : [in] "r" (in), "[rounds]" (rounds), "[rc]" (rc) ); } int crypto_aead_encrypt(unsigned char *c, unsigned long long *clen, const unsigned char *m, unsigned long long mlen, const unsigned char *ad, unsigned long long adlen, const unsigned char *nsec, const unsigned char *npub, const unsigned char *k) { unsigned int i, j; u32 s[8] = { 0 }; u32 dataFormat[2] = { 0 }; u8 tempData[8]; u32 s_temp[8] = { 0 }; u32 t1, t2, t3, t5, t6, t8, t9, t11; *clen = mlen + CRYPTO_ABYTES; //initialization packFormat(s, npub); packFormat((s + 2), (npub + 8)); packFormat((s + 4), k); packFormat((s + 6), (k + 8)); permutation256(s,PR0_ROUNDS,constant6Format); // process associated data if (adlen) { while (adlen >= RATE) { packFormat(dataFormat, ad); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; permutation256(s,PR_ROUNDS,constant6Format); adlen -= RATE; ad += RATE; } memset(tempData, 0, sizeof(tempData)); memcpy(tempData, ad, adlen * sizeof(unsigned char)); tempData[adlen] = 0x01; packFormat(dataFormat, tempData); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; permutation256(s,PR_ROUNDS,constant6Format); } s[6] ^= 0x80000000; if (mlen) { while (mlen >= RATE) { packFormat(dataFormat, m); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; unpackFormat(c, s); permutation256(s,PR_ROUNDS,constant6Format); mlen -= RATE; m += RATE; c += RATE; } memset(tempData, 0, sizeof(tempData)); memcpy(tempData, m, mlen * sizeof(unsigned char)); tempData[mlen]= 0x01; packFormat(dataFormat, tempData); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; unpackFormat(tempData, s); memcpy(c, tempData, mlen * sizeof(unsigned char)); c +=mlen; } // finalization permutation256(s,PRF_ROUNDS,constant6Format); // return tag unpackFormat(tempData, s); memcpy(c, tempData, sizeof(tempData)); unpackFormat(tempData,(s + 2)); memcpy(c+8, tempData, sizeof(tempData)); // unpackFormat((c), s); // unpackFormat((c+8),(s + 2)); return 0; } int crypto_aead_decrypt(unsigned char *m, unsigned long long *mlen, unsigned char *nsec, const unsigned char *c, unsigned long long clen, const unsigned char *ad, unsigned long long adlen, const unsigned char *npub, const unsigned char *k) { u8 i, j; // initialization u32 s[8] = { 0 }; u32 dataFormat[4] = { 0 }; u32 dataFormat_1[2] = { 0 }; u8 tempU8[32] = { 0 }; u8 tempData[8]; u32 s_temp[8] = { 0 }; u32 t1, t2, t3, t5, t6, t8, t9, t11; *mlen = clen - CRYPTO_ABYTES; if (clen < CRYPTO_ABYTES) return -1; //initialization packFormat(s, npub); packFormat((s + 2), (npub + 8)); packFormat((s + 4), k); packFormat((s + 6), (k + 8)); permutation256(s,PR0_ROUNDS,constant6Format); // process associated data if (adlen) { while (adlen >= RATE) { packFormat(dataFormat, ad); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; permutation256(s,PR_ROUNDS,constant6Format); adlen -= RATE; ad += RATE; } memset(tempData, 0, sizeof(tempData)); memcpy(tempData, ad, adlen * sizeof(unsigned char)); tempData[adlen] = 0x01; packFormat(dataFormat, tempData); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; permutation256(s,PR_ROUNDS,constant6Format); } s[6] ^= 0x80000000; // process c clen = clen - CRYPTO_KEYBYTES; if (clen) { while (clen >= RATE) { packFormat(dataFormat, c); dataFormat_1[0] = s[0] ^ dataFormat[0]; dataFormat_1[1] = s[1] ^ dataFormat[1]; unpackFormat(m, dataFormat_1); s[0] = dataFormat[0]; s[1] = dataFormat[1]; permutation256(s,PR_ROUNDS,constant6Format); clen -= RATE; m += RATE; c += RATE; } unpackFormat(tempU8, s); for (i = 0; i < clen; ++i, ++m, ++c) { *m = tempU8[i]^ *c; tempU8[i] = *c; } tempU8[i] ^= 0x01; packFormat(s, tempU8); } // finalization permutation256(s,PRF_ROUNDS,constant6Format); // return tag packFormat(dataFormat, c); packFormat((dataFormat + 2), (c +8)); if (dataFormat[0] != s[0] || dataFormat[1] != s[1] || dataFormat[2] != s[2] || dataFormat[3] != s[3]) { return -1; } return 0; }