#include"auxFormat.h" #define aead_RATE (128 / 8) #define PR0_ROUNDS 100 #define PR_ROUNDS 52 #define PRF_ROUNDS 56 unsigned char constant7Format_aead[127] = { /*constant7_aead_256*/ 0x1, 0x4, 0x10, 0x40, 0x2, 0x8, 0x21, 0x5, 0x14, 0x50, 0x42, 0xa, 0x29, 0x24, 0x11, 0x44, 0x12, 0x48, 0x23, 0xd, 0x35, 0x55, 0x56, 0x5a, 0x6b, 0x2e, 0x38, 0x60, 0x3, 0xc, 0x31, 0x45, 0x16, 0x58, 0x63, 0xf, 0x3d, 0x74, 0x53, 0x4e, 0x3b, 0x6c, 0x32, 0x49, 0x27, 0x1d, 0x75, 0x57, 0x5e, 0x7b, 0x6e, 0x3a, 0x68, 0x22, 0x9, 0x25, 0x15, 0x54, 0x52, 0x4a, 0x2b, 0x2c, 0x30, 0x41, 0x6, 0x18, 0x61, 0x7, 0x1c, 0x71, 0x47, 0x1e, 0x79, 0x66, 0x1b, 0x6d, 0x36, 0x59, 0x67, 0x1f, 0x7d, 0x76, 0x5b, 0x6f, 0x3e, 0x78, 0x62, 0xb, 0x2d, 0x34, 0x51, 0x46, 0x1a, 0x69, 0x26, 0x19, 0x65, 0x17, 0x5c, 0x73, 0x4f, 0x3f, 0x7c, 0x72, 0x4b, 0x2f, 0x3c, 0x70, 0x43, 0xe, 0x39, 0x64, 0x13, 0x4c, 0x33, 0x4d, 0x37, 0x5d, 0x77, 0x5f, 0x7f, 0x7e, 0x7a, 0x6a, 0x2a, 0x28, 0x20, }; /* State * w12 w8 w4 w0 * w13 w9 w5 w1 * w14 w10 w6 w2 * w15 w11 w7 w3 * */ static void permutation512(unsigned int *in, int rounds, unsigned char *rc) { uint32_t w0, w1, w2, w3, w4, w5, w6, w7; uint32_t w8, w9, w10, w11, w12, w13, w14, w15; uint32_t s0, s1, s2,s3; uint32_t i=0; __asm volatile( "ldr w0, [in] \n\t" "ldr w4, [in, #4] \n\t" "ldr w8, [in, #8] \n\t" "ldr w12, [in, #12] \n\t" "ldr w1, [in, #16] \n\t" "ldr w5, [in, #20] \n\t" "ldr w9, [in, #24] \n\t" "ldr w13, [in, #28] \n\t" "ldr w2, [in, #32] \n\t" "ldr w6, [in, #36] \n\t" "ldr w10, [in, #40] \n\t" "ldr w14, [in, #44] \n\t" "ldr w3, [in, #48] \n\t" "ldr w7, [in, #52] \n\t" "ldr w11, [in, #56] \n\t" "ldr w15, [in, #60] \n\t" "enc_loop: \n\t" "/*add round const s0 s1 s2 s3*/ \n\t" "ldrb s3, [rc] \n\t" "LSR s0, s3, #6 \n\t" "and s0, s0, 0x3 \n\t" "LSR s1, s3, #4 \n\t" "and s1, s1, 0x3 \n\t" "LSR s2, s3, #2 \n\t" "and s2, s2, 0x3 \n\t" "and s3, s3, 0x3 \n\t" "eors w12, w12, s0 \n\t" "eors w8, w8, s1 \n\t" "eors w4, w4, s2 \n\t" "eors w0, w0, s3 \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" "/*sbox third column*/ \n\t" "mvns w8, w8 \n\t" "ands s0, w9, w8 \n\t" "eors s0, w10, s0 \n\t" "orrs w10, w9, w10 \n\t" "eors w8, w11, w8 \n\t" "eors w10, w10, w8 \n\t" "eors s1, w9, w11 \n\t" "eors w11, w11, s0 \n\t" "ands w8, s0, w8 \n\t" "eors w8, s1, w8 \n\t" "ands w9, w10, s1 \n\t" "eors w9, s0, w9 \n\t" "/*sbox forth column*/ \n\t" "mvns w12, w12 \n\t" "ands s0, w13, w12 \n\t" "eors s0, w14, s0 \n\t" "orrs w14, w13, w14 \n\t" "eors w12, w15, w12 \n\t" "eors w14, w14, w12 \n\t" "eors s1, w13, w15 \n\t" "eors w15, w15, s0 \n\t" "ands w12, s0, w12 \n\t" "eors w12, s1, w12 \n\t" "ands w13, w14, s1 \n\t" "eors w13, s0, w13 \n\t" "/*rotate shift left 1 bit [ w13 w9 w5 w1-> w9 w5 w1 (w13,1)] */ \n\t" "mov s0, w13 \n\t" "mov w13, w9 \n\t" "mov w9, w5 \n\t" "mov w5, w1 \n\t" "ROR w1, s0 , #31 \n\t" "/*rotate shift left 8 bits [w14 w10 w6 w2->£¨w14,4) £¨w10,4) (w6,4) ( w2,4)]*/ \n\t" "ROR w14, w14 , #28 \n\t" "ROR w10, w10 , #28 \n\t" "ROR w6, w6 , #28 \n\t" "ROR w2, w2 , #28 \n\t" "/*rotate shift left 25 bit [w15 w11 w7 w3-> £¨w11,13) (w7,14) ( w3,14) ( w15,14)] */ \n\t" "mov s0, w15 \n\t" "ROR w15, w11 , #26 \n\t" "ROR w11, w7 , #26 \n\t" "ROR w7 , w3 , #26 \n\t" "ROR w3 , s0 , #25 \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 w8, [in, #8] \n\t" "str w12, [in, #12] \n\t" "str w1, [in, #16] \n\t" "str w5, [in, #20] \n\t" "str w9, [in, #24] \n\t" "str w13, [in, #28] \n\t" "str w2, [in, #32] \n\t" "str w6, [in, #36] \n\t" "str w10, [in, #40] \n\t" "str w14, [in, #44] \n\t" "str w3, [in, #48] \n\t" "str w7, [in, #52] \n\t" "str w11, [in, #56] \n\t" "str w15, [in, #60] \n\t" ); } 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 ) { u32 i, j; u32 s_temp[16] = { 0 }; u32 t1, t2, t3, t5, t6, t8, t9, t11; // initialization u32 s[16] = { 0 }; u32 dataFormat[4] = { 0 }; u8 tempData[16] = {0}; *clen = mlen + CRYPTO_ABYTES; //initialization packU128FormatToFourPacket(s, npub); packU128FormatToFourPacket((s + 4), (npub + 16)); packU128FormatToFourPacket((s + 8), k); packU128FormatToFourPacket((s + 12), (k + 16)); permutation512(s,PR0_ROUNDS,constant7Format_aead); // process associated data if (adlen) { while (adlen >= aead_RATE) { packU128FormatToFourPacket(dataFormat, ad); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; s[2] ^= dataFormat[2]; s[3] ^= dataFormat[3]; permutation512(s,PR_ROUNDS,constant7Format_aead); adlen -= aead_RATE; ad += aead_RATE; } memset(tempData, 0, sizeof(tempData)); memcpy(tempData, ad, adlen * sizeof(unsigned char)); tempData[adlen] = 0x01; packU128FormatToFourPacket(dataFormat, tempData); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; s[2] ^= dataFormat[2]; s[3] ^= dataFormat[3]; permutation512(s,PR_ROUNDS,constant7Format_aead); } s[15] ^= 0x80000000; if (mlen) { while (mlen >= aead_RATE) { packU128FormatToFourPacket(dataFormat, m); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; s[2] ^= dataFormat[2]; s[3] ^= dataFormat[3]; unpackU128FormatToFourPacket(c, s); permutation512(s,PR_ROUNDS,constant7Format_aead); mlen -= aead_RATE; m += aead_RATE; c += aead_RATE; } memset(tempData, 0, sizeof(tempData)); memcpy(tempData, m, mlen * sizeof(unsigned char)); tempData[mlen]= 0x01; packU128FormatToFourPacket(dataFormat, tempData); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; s[2] ^= dataFormat[2]; s[3] ^= dataFormat[3]; unpackU128FormatToFourPacket(tempData, s); memcpy(c, tempData, mlen * sizeof(unsigned char)); c += mlen; } // finalization permutation512(s,PRF_ROUNDS,constant7Format_aead); // return tag unpackU128FormatToFourPacket(c, s); unpackU128FormatToFourPacket((c+16), (s+4)); 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 ){ u32 s_temp[16] = { 0 }; u32 t1, t2, t3, t5, t6, t8, t9, t11; u8 i, j; // initialization u32 s[16] = { 0 }; u32 dataFormat[4] = { 0 }; u32 dataFormat_1[4] = { 0 }; u32 dataFormat_2[4] = { 0 }; u8 tempData[16] = { 0 }; u8 tempU8[64] = { 0 }; if (clen < CRYPTO_ABYTES) return -1; *mlen = clen - CRYPTO_ABYTES; //initialization packU128FormatToFourPacket(s, npub); packU128FormatToFourPacket((s + 4), (npub + 16)); packU128FormatToFourPacket((s + 8), k); packU128FormatToFourPacket((s + 12), (k + 16)); permutation512(s,PR0_ROUNDS,constant7Format_aead); // process associated data if (adlen) { while (adlen >= aead_RATE) { packU128FormatToFourPacket(dataFormat, ad); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; s[2] ^= dataFormat[2]; s[3] ^= dataFormat[3]; permutation512(s,PR_ROUNDS,constant7Format_aead); adlen -= aead_RATE; ad += aead_RATE; } memset(tempData, 0, sizeof(tempData)); memcpy(tempData, ad, adlen * sizeof(unsigned char)); tempData[adlen] = 0x01; packU128FormatToFourPacket(dataFormat, tempData); s[0] ^= dataFormat[0]; s[1] ^= dataFormat[1]; s[2] ^= dataFormat[2]; s[3] ^= dataFormat[3]; permutation512(s,PR_ROUNDS,constant7Format_aead); } s[15] ^= 0x80000000; clen = clen - CRYPTO_KEYBYTES; if (clen) { while (clen >= aead_RATE) { packU128FormatToFourPacket(dataFormat_2, c); dataFormat_1[0] = s[0] ^ dataFormat_2[0]; dataFormat_1[1] = s[1] ^ dataFormat_2[1]; dataFormat_1[2] = s[2] ^ dataFormat_2[2]; dataFormat_1[3] = s[3] ^ dataFormat_2[3]; unpackU128FormatToFourPacket(m, dataFormat_1); s[0] = dataFormat_2[0]; s[1] = dataFormat_2[1]; s[2] = dataFormat_2[2]; s[3] = dataFormat_2[3]; permutation512(s,PR_ROUNDS,constant7Format_aead); clen -= aead_RATE; m += aead_RATE; c += aead_RATE; } unpackU128FormatToFourPacket(tempU8, s); for (i = 0; i < clen; ++i, ++m, ++c) { *m = tempU8[i] ^ *c; tempU8[i] = *c; } tempU8[i] ^= 0x01; packU128FormatToFourPacket(s, tempU8); } // finalization permutation512(s,PRF_ROUNDS,constant7Format_aead); // return tag packU128FormatToFourPacket(dataFormat, c); packU128FormatToFourPacket(dataFormat_1, (c + 16)); if (dataFormat[0] != s[0] || dataFormat[1] != s[1] || dataFormat[2] != s[2] || dataFormat[3] != s[3] || dataFormat_1[0] != s[4] || dataFormat_1[1] != s[5] || dataFormat_1[2] != s[6] || dataFormat_1[3] != s[7]) { return -1; } return 0; }