33 #if defined(FORKAE_ALG_NAME)
35 #define FORKAE_CONCAT_INNER(name,suffix) name##suffix
36 #define FORKAE_CONCAT(name,suffix) FORKAE_CONCAT_INNER(name,suffix)
39 STATIC_INLINE
int FORKAE_CONCAT(FORKAE_ALG_NAME,_is_padding)
40 (
const unsigned char *block,
unsigned len)
42 int check = block[0] ^ 0x80;
47 return (check - 1) >> 8;
50 int FORKAE_CONCAT(FORKAE_ALG_NAME,_aead_encrypt)
51 (
unsigned char *c,
unsigned long long *clen,
52 const unsigned char *m,
unsigned long long mlen,
53 const unsigned char *ad,
unsigned long long adlen,
54 const unsigned char *nsec,
55 const unsigned char *npub,
56 const unsigned char *k)
58 unsigned char tweakey[FORKAE_TWEAKEY_SIZE];
59 unsigned char tag[FORKAE_BLOCK_SIZE];
60 unsigned char block[FORKAE_BLOCK_SIZE];
64 *clen = mlen + FORKAE_BLOCK_SIZE;
67 memcpy(tweakey, k, 16);
68 memcpy(tweakey + 16, npub, FORKAE_NONCE_SIZE);
69 memset(tweakey + 16 + FORKAE_NONCE_SIZE, 0,
70 FORKAE_TWEAKEY_SIZE - 16 - FORKAE_NONCE_SIZE);
71 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] = 0x08;
74 memset(tag, 0,
sizeof(tag));
77 if (adlen > 0 || mlen == 0) {
78 while (adlen > FORKAE_BLOCK_SIZE) {
79 lw_xor_block(tag, ad, FORKAE_BLOCK_SIZE);
80 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, tag, tag);
81 memset(tweakey + 16, 0, FORKAE_TWEAKEY_SIZE - 16);
82 ad += FORKAE_BLOCK_SIZE;
83 adlen -= FORKAE_BLOCK_SIZE;
86 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x04;
87 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x02;
88 if (adlen == FORKAE_BLOCK_SIZE) {
89 lw_xor_block(tag, ad, FORKAE_BLOCK_SIZE);
90 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, tag, tag);
91 memset(tweakey + 16, 0, FORKAE_TWEAKEY_SIZE - 16);
92 }
else if (adlen != 0 || mlen == 0) {
93 unsigned temp = (unsigned)adlen;
94 lw_xor_block(tag, ad, temp);
96 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x01;
97 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, tag, tag);
98 memset(tweakey + 16, 0, FORKAE_TWEAKEY_SIZE - 16);
104 memcpy(c, tag,
sizeof(tag));
109 while (mlen > FORKAE_BLOCK_SIZE) {
110 lw_xor_block_2_src(block, m, tag, FORKAE_BLOCK_SIZE);
111 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x01;
112 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, c, block, block);
113 lw_xor_block(c, tag, FORKAE_BLOCK_SIZE);
114 memcpy(tag, block, FORKAE_BLOCK_SIZE);
115 memset(tweakey + 16, 0, FORKAE_TWEAKEY_SIZE - 16);
116 c += FORKAE_BLOCK_SIZE;
117 m += FORKAE_BLOCK_SIZE;
118 mlen -= FORKAE_BLOCK_SIZE;
122 if (mlen == FORKAE_BLOCK_SIZE) {
123 lw_xor_block_2_src(block, m, tag, FORKAE_BLOCK_SIZE);
124 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x04;
125 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, c, block, block);
126 lw_xor_block(c, tag, FORKAE_BLOCK_SIZE);
127 memcpy(c + FORKAE_BLOCK_SIZE, block, FORKAE_BLOCK_SIZE);
129 unsigned temp = (unsigned)mlen;
130 memcpy(block, tag, FORKAE_BLOCK_SIZE);
131 lw_xor_block(block, m, temp);
133 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x05;
134 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, c, block, block);
135 lw_xor_block(c, tag, FORKAE_BLOCK_SIZE);
136 memcpy(c + FORKAE_BLOCK_SIZE, block, temp);
141 int FORKAE_CONCAT(FORKAE_ALG_NAME,_aead_decrypt)
142 (
unsigned char *m,
unsigned long long *mlen,
144 const unsigned char *c,
unsigned long long clen,
145 const unsigned char *ad,
unsigned long long adlen,
146 const unsigned char *npub,
147 const unsigned char *k)
149 unsigned char tweakey[FORKAE_TWEAKEY_SIZE];
150 unsigned char tag[FORKAE_BLOCK_SIZE];
151 unsigned char block[FORKAE_BLOCK_SIZE];
152 unsigned char *mtemp = m;
156 if (clen < FORKAE_BLOCK_SIZE)
158 clen -= FORKAE_BLOCK_SIZE;
162 memcpy(tweakey, k, 16);
163 memcpy(tweakey + 16, npub, FORKAE_NONCE_SIZE);
164 memset(tweakey + 16 + FORKAE_NONCE_SIZE, 0,
165 FORKAE_TWEAKEY_SIZE - 16 - FORKAE_NONCE_SIZE);
166 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] = 0x08;
169 memset(tag, 0,
sizeof(tag));
172 if (adlen > 0 || clen == 0) {
173 while (adlen > FORKAE_BLOCK_SIZE) {
174 lw_xor_block(tag, ad, FORKAE_BLOCK_SIZE);
175 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, tag, tag);
176 memset(tweakey + 16, 0, FORKAE_TWEAKEY_SIZE - 16);
177 ad += FORKAE_BLOCK_SIZE;
178 adlen -= FORKAE_BLOCK_SIZE;
181 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x04;
182 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x02;
183 if (adlen == FORKAE_BLOCK_SIZE) {
184 lw_xor_block(tag, ad, FORKAE_BLOCK_SIZE);
185 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, tag, tag);
186 memset(tweakey + 16, 0, FORKAE_TWEAKEY_SIZE - 16);
187 }
else if (adlen != 0 || clen == 0) {
188 unsigned temp = (unsigned)adlen;
189 lw_xor_block(tag, ad, temp);
191 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x01;
192 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, tag, tag);
193 memset(tweakey + 16, 0, FORKAE_TWEAKEY_SIZE - 16);
202 while (clen > FORKAE_BLOCK_SIZE) {
203 lw_xor_block_2_src(block, c, tag, FORKAE_BLOCK_SIZE);
204 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x01;
205 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_decrypt)(tweakey, m, block, block);
206 lw_xor_block(m, tag, FORKAE_BLOCK_SIZE);
207 memcpy(tag, block, FORKAE_BLOCK_SIZE);
208 memset(tweakey + 16, 0, FORKAE_TWEAKEY_SIZE - 16);
209 c += FORKAE_BLOCK_SIZE;
210 m += FORKAE_BLOCK_SIZE;
211 clen -= FORKAE_BLOCK_SIZE;
215 if (clen == FORKAE_BLOCK_SIZE) {
216 lw_xor_block_2_src(block, c, tag, FORKAE_BLOCK_SIZE);
217 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x04;
218 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_decrypt)(tweakey, m, block, block);
219 lw_xor_block(m, tag, FORKAE_BLOCK_SIZE);
221 (mtemp, *mlen, block, c + FORKAE_BLOCK_SIZE, FORKAE_BLOCK_SIZE);
223 unsigned temp = (unsigned)clen;
224 unsigned char mblock[FORKAE_BLOCK_SIZE];
226 lw_xor_block_2_src(block, c, tag, FORKAE_BLOCK_SIZE);
227 tweakey[FORKAE_TWEAKEY_REDUCED_SIZE - 1] ^= 0x05;
228 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_decrypt)
229 (tweakey, mblock, block, block);
230 lw_xor_block(mblock, tag, FORKAE_BLOCK_SIZE);
231 memcpy(m, mblock, temp);
232 check = FORKAE_CONCAT(FORKAE_ALG_NAME,_is_padding)
233 (mblock + temp, FORKAE_BLOCK_SIZE - temp);
235 (mtemp, *mlen, block, c + FORKAE_BLOCK_SIZE, temp, check);
243 #undef FORKAE_ALG_NAME
244 #undef FORKAE_BLOCK_SIZE
245 #undef FORKAE_NONCE_SIZE
246 #undef FORKAE_COUNTER_SIZE
247 #undef FORKAE_TWEAKEY_SIZE
248 #undef FORKAE_TWEAKEY_REDUCED_SIZE
249 #undef FORKAE_BLOCK_FUNC
250 #undef FORKAE_CONCAT_INNER
int aead_check_tag(unsigned char *plaintext, unsigned long long plaintext_len, const unsigned char *tag1, const unsigned char *tag2, unsigned tag_len)
Check an authentication tag in constant time.
Definition: aead-common.c:26
int aead_check_tag_precheck(unsigned char *plaintext, unsigned long long plaintext_len, const unsigned char *tag1, const unsigned char *tag2, unsigned tag_len, int precheck)
Check an authentication tag in constant time with a previous check.
Definition: aead-common.c:49