aead_aes256gcm_aesni.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  1. /*
  2. * AES256-GCM, based on the "Intel Carry-Less Multiplication Instruction and its Usage for Computing
  3. * the GCM Mode" paper and reference code, using the aggregated reduction method.
  4. * Originally adapted by Romain Dolbeau.
  5. */
  6. #include <errno.h>
  7. #include <stdint.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "core.h"
  11. #include "crypto_aead_aes256gcm.h"
  12. #include "export.h"
  13. #include "private/common.h"
  14. #include "private/sse2_64_32.h"
  15. #include "randombytes.h"
  16. #include "runtime.h"
  17. #include "utils.h"
  18. #if defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H)
  19. # ifdef __GNUC__
  20. # pragma GCC target("ssse3")
  21. # pragma GCC target("aes")
  22. # pragma GCC target("pclmul")
  23. # endif
  24. #include <tmmintrin.h>
  25. #include <wmmintrin.h>
  26. #ifndef ENOSYS
  27. # define ENOSYS ENXIO
  28. #endif
  29. #if defined(__INTEL_COMPILER) || defined(_bswap64)
  30. #elif defined(_MSC_VER)
  31. # define _bswap64(a) _byteswap_uint64(a)
  32. #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
  33. # define _bswap64(a) __builtin_bswap64(a)
  34. #else
  35. static inline uint64_t
  36. _bswap64(const uint64_t x)
  37. {
  38. return
  39. ((x << 56) & 0xFF00000000000000UL) | ((x << 40) & 0x00FF000000000000UL) |
  40. ((x << 24) & 0x0000FF0000000000UL) | ((x << 8) & 0x000000FF00000000UL) |
  41. ((x >> 8) & 0x00000000FF000000UL) | ((x >> 24) & 0x0000000000FF0000UL) |
  42. ((x >> 40) & 0x000000000000FF00UL) | ((x >> 56) & 0x00000000000000FFUL);
  43. }
  44. #endif
  45. typedef struct aes256gcm_state {
  46. __m128i rkeys[16];
  47. unsigned char H[16];
  48. } aes256gcm_state;
  49. static inline void
  50. aesni_key256_expand(const unsigned char *key, __m128i * const rkeys)
  51. {
  52. __m128i X0, X1, X2, X3;
  53. int i = 0;
  54. X0 = _mm_loadu_si128((const __m128i *) &key[0]);
  55. rkeys[i++] = X0;
  56. X2 = _mm_loadu_si128((const __m128i *) &key[16]);
  57. rkeys[i++] = X2;
  58. #define EXPAND_KEY_1(S) do { \
  59. X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X2, (S)), 0xff); \
  60. X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x10)); \
  61. X0 = _mm_xor_si128(X0, X3); \
  62. X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x8c)); \
  63. X0 = _mm_xor_si128(_mm_xor_si128(X0, X3), X1); \
  64. rkeys[i++] = X0; \
  65. } while (0)
  66. #define EXPAND_KEY_2(S) do { \
  67. X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X0, (S)), 0xaa); \
  68. X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x10)); \
  69. X2 = _mm_xor_si128(X2, X3); \
  70. X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x8c)); \
  71. X2 = _mm_xor_si128(_mm_xor_si128(X2, X3), X1); \
  72. rkeys[i++] = X2; \
  73. } while (0)
  74. X3 = _mm_setzero_si128();
  75. EXPAND_KEY_1(0x01); EXPAND_KEY_2(0x01);
  76. EXPAND_KEY_1(0x02); EXPAND_KEY_2(0x02);
  77. EXPAND_KEY_1(0x04); EXPAND_KEY_2(0x04);
  78. EXPAND_KEY_1(0x08); EXPAND_KEY_2(0x08);
  79. EXPAND_KEY_1(0x10); EXPAND_KEY_2(0x10);
  80. EXPAND_KEY_1(0x20); EXPAND_KEY_2(0x20);
  81. EXPAND_KEY_1(0x40);
  82. }
  83. /** single, by-the-book AES encryption with AES-NI */
  84. static inline void
  85. aesni_encrypt1(unsigned char *out, __m128i nv, const __m128i *rkeys)
  86. {
  87. __m128i temp = _mm_xor_si128(nv, rkeys[0]);
  88. temp = _mm_aesenc_si128(temp, rkeys[1]);
  89. temp = _mm_aesenc_si128(temp, rkeys[2]);
  90. temp = _mm_aesenc_si128(temp, rkeys[3]);
  91. temp = _mm_aesenc_si128(temp, rkeys[4]);
  92. temp = _mm_aesenc_si128(temp, rkeys[5]);
  93. temp = _mm_aesenc_si128(temp, rkeys[6]);
  94. temp = _mm_aesenc_si128(temp, rkeys[7]);
  95. temp = _mm_aesenc_si128(temp, rkeys[8]);
  96. temp = _mm_aesenc_si128(temp, rkeys[9]);
  97. temp = _mm_aesenc_si128(temp, rkeys[10]);
  98. temp = _mm_aesenc_si128(temp, rkeys[11]);
  99. temp = _mm_aesenc_si128(temp, rkeys[12]);
  100. temp = _mm_aesenc_si128(temp, rkeys[13]);
  101. temp = _mm_aesenclast_si128(temp, rkeys[14]);
  102. _mm_storeu_si128((__m128i *) out, temp);
  103. }
  104. /** multiple-blocks-at-once AES encryption with AES-NI ;
  105. on Haswell, aesenc has a latency of 7 and a throughput of 1
  106. so the sequence of aesenc should be bubble-free if you
  107. have at least 8 blocks. Let's build an arbitratry-sized
  108. function */
  109. /* Step 1 : loading the nonce */
  110. /* load & increment the n vector (non-vectorized, unused for now) */
  111. #define NVDECLx(a) \
  112. __m128i nv##a
  113. #define NVx(a) \
  114. nv##a = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) n), pt); \
  115. n[3]++
  116. /* Step 2 : define value in round one (xor with subkey #0, aka key) */
  117. #define TEMPDECLx(a) \
  118. __m128i temp##a
  119. #define TEMPx(a) \
  120. temp##a = _mm_xor_si128(nv##a, rkeys[0])
  121. /* Step 3: one round of AES */
  122. #define AESENCx(a) \
  123. temp##a = _mm_aesenc_si128(temp##a, rkeys[roundctr])
  124. /* Step 4: last round of AES */
  125. #define AESENCLASTx(a) \
  126. temp##a = _mm_aesenclast_si128(temp##a, rkeys[14])
  127. /* Step 5: store result */
  128. #define STOREx(a) \
  129. _mm_storeu_si128((__m128i *) (out + (a * 16)), temp##a)
  130. /* all the MAKE* macros are for automatic explicit unrolling */
  131. #define MAKE4(X) \
  132. X(0); \
  133. X(1); \
  134. X(2); \
  135. X(3)
  136. #define MAKE8(X) \
  137. X(0); \
  138. X(1); \
  139. X(2); \
  140. X(3); \
  141. X(4); \
  142. X(5); \
  143. X(6); \
  144. X(7)
  145. #define COUNTER_INC2(N) (N)[3] += 2
  146. /* create a function of unrolling N ; the MAKEN is the unrolling
  147. macro, defined above. The N in MAKEN must match N, obviously. */
  148. #define FUNC(N, MAKEN) \
  149. static inline void aesni_encrypt##N(unsigned char *out, uint32_t *n, const __m128i *rkeys) \
  150. { \
  151. const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
  152. int roundctr; \
  153. MAKEN(NVDECLx); \
  154. MAKEN(TEMPDECLx); \
  155. \
  156. MAKEN(NVx); \
  157. MAKEN(TEMPx); \
  158. for (roundctr = 1; roundctr < 14; roundctr++) { \
  159. MAKEN(AESENCx); \
  160. } \
  161. MAKEN(AESENCLASTx); \
  162. MAKEN(STOREx); \
  163. }
  164. FUNC(8, MAKE8)
  165. /* all GF(2^128) fnctions are by the book, meaning this one:
  166. <https://software.intel.com/sites/default/files/managed/72/cc/clmul-wp-rev-2.02-2014-04-20.pdf>
  167. */
  168. static inline void
  169. addmul(unsigned char *c, const unsigned char *a, unsigned int xlen, const unsigned char *b)
  170. {
  171. const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
  172. __m128i A, B, C;
  173. __m128i tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
  174. __m128i tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18;
  175. __m128i tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27;
  176. __m128i tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36;
  177. if (xlen >= 16) {
  178. A = _mm_loadu_si128((const __m128i *) a);
  179. } else {
  180. CRYPTO_ALIGN(16) unsigned char padded[16];
  181. unsigned int i;
  182. memset(padded, 0, 16);
  183. for (i = 0; i < xlen; i++) {
  184. padded[i] = a[i];
  185. }
  186. A = _mm_load_si128((const __m128i *) padded);
  187. }
  188. A = _mm_shuffle_epi8(A, rev);
  189. B = _mm_loadu_si128((const __m128i *) b);
  190. C = _mm_loadu_si128((const __m128i *) c);
  191. A = _mm_xor_si128(A, C);
  192. tmp3 = _mm_clmulepi64_si128(A, B, 0x00);
  193. tmp4 = _mm_clmulepi64_si128(A, B, 0x10);
  194. tmp5 = _mm_clmulepi64_si128(A, B, 0x01);
  195. tmp6 = _mm_clmulepi64_si128(A, B, 0x11);
  196. tmp10 = _mm_xor_si128(tmp4, tmp5);
  197. tmp13 = _mm_slli_si128(tmp10, 8);
  198. tmp11 = _mm_srli_si128(tmp10, 8);
  199. tmp15 = _mm_xor_si128(tmp3, tmp13);
  200. tmp17 = _mm_xor_si128(tmp6, tmp11);
  201. tmp7 = _mm_srli_epi32(tmp15, 31);
  202. tmp8 = _mm_srli_epi32(tmp17, 31);
  203. tmp16 = _mm_slli_epi32(tmp15, 1);
  204. tmp18 = _mm_slli_epi32(tmp17, 1);
  205. tmp9 = _mm_srli_si128(tmp7, 12);
  206. tmp22 = _mm_slli_si128(tmp8, 4);
  207. tmp25 = _mm_slli_si128(tmp7, 4);
  208. tmp29 = _mm_or_si128(tmp16, tmp25);
  209. tmp19 = _mm_or_si128(tmp18, tmp22);
  210. tmp20 = _mm_or_si128(tmp19, tmp9);
  211. tmp26 = _mm_slli_epi32(tmp29, 31);
  212. tmp23 = _mm_slli_epi32(tmp29, 30);
  213. tmp32 = _mm_slli_epi32(tmp29, 25);
  214. tmp27 = _mm_xor_si128(tmp26, tmp23);
  215. tmp28 = _mm_xor_si128(tmp27, tmp32);
  216. tmp24 = _mm_srli_si128(tmp28, 4);
  217. tmp33 = _mm_slli_si128(tmp28, 12);
  218. tmp30 = _mm_xor_si128(tmp29, tmp33);
  219. tmp2 = _mm_srli_epi32(tmp30, 1);
  220. tmp12 = _mm_srli_epi32(tmp30, 2);
  221. tmp14 = _mm_srli_epi32(tmp30, 7);
  222. tmp34 = _mm_xor_si128(tmp2, tmp12);
  223. tmp35 = _mm_xor_si128(tmp34, tmp14);
  224. tmp36 = _mm_xor_si128(tmp35, tmp24);
  225. tmp31 = _mm_xor_si128(tmp30, tmp36);
  226. tmp21 = _mm_xor_si128(tmp20, tmp31);
  227. _mm_storeu_si128((__m128i *) c, tmp21);
  228. }
  229. /* pure multiplication, for pre-computing powers of H */
  230. static inline __m128i
  231. mulv(__m128i A, __m128i B)
  232. {
  233. __m128i tmp3 = _mm_clmulepi64_si128(A, B, 0x00);
  234. __m128i tmp4 = _mm_clmulepi64_si128(A, B, 0x10);
  235. __m128i tmp5 = _mm_clmulepi64_si128(A, B, 0x01);
  236. __m128i tmp6 = _mm_clmulepi64_si128(A, B, 0x11);
  237. __m128i tmp10 = _mm_xor_si128(tmp4, tmp5);
  238. __m128i tmp13 = _mm_slli_si128(tmp10, 8);
  239. __m128i tmp11 = _mm_srli_si128(tmp10, 8);
  240. __m128i tmp15 = _mm_xor_si128(tmp3, tmp13);
  241. __m128i tmp17 = _mm_xor_si128(tmp6, tmp11);
  242. __m128i tmp7 = _mm_srli_epi32(tmp15, 31);
  243. __m128i tmp8 = _mm_srli_epi32(tmp17, 31);
  244. __m128i tmp16 = _mm_slli_epi32(tmp15, 1);
  245. __m128i tmp18 = _mm_slli_epi32(tmp17, 1);
  246. __m128i tmp9 = _mm_srli_si128(tmp7, 12);
  247. __m128i tmp22 = _mm_slli_si128(tmp8, 4);
  248. __m128i tmp25 = _mm_slli_si128(tmp7, 4);
  249. __m128i tmp29 = _mm_or_si128(tmp16, tmp25);
  250. __m128i tmp19 = _mm_or_si128(tmp18, tmp22);
  251. __m128i tmp20 = _mm_or_si128(tmp19, tmp9);
  252. __m128i tmp26 = _mm_slli_epi32(tmp29, 31);
  253. __m128i tmp23 = _mm_slli_epi32(tmp29, 30);
  254. __m128i tmp32 = _mm_slli_epi32(tmp29, 25);
  255. __m128i tmp27 = _mm_xor_si128(tmp26, tmp23);
  256. __m128i tmp28 = _mm_xor_si128(tmp27, tmp32);
  257. __m128i tmp24 = _mm_srli_si128(tmp28, 4);
  258. __m128i tmp33 = _mm_slli_si128(tmp28, 12);
  259. __m128i tmp30 = _mm_xor_si128(tmp29, tmp33);
  260. __m128i tmp2 = _mm_srli_epi32(tmp30, 1);
  261. __m128i tmp12 = _mm_srli_epi32(tmp30, 2);
  262. __m128i tmp14 = _mm_srli_epi32(tmp30, 7);
  263. __m128i tmp34 = _mm_xor_si128(tmp2, tmp12);
  264. __m128i tmp35 = _mm_xor_si128(tmp34, tmp14);
  265. __m128i tmp36 = _mm_xor_si128(tmp35, tmp24);
  266. __m128i tmp31 = _mm_xor_si128(tmp30, tmp36);
  267. __m128i C = _mm_xor_si128(tmp20, tmp31);
  268. return C;
  269. }
  270. /* 4 multiply-accumulate at once; again
  271. <https://software.intel.com/sites/default/files/managed/72/cc/clmul-wp-rev-2.02-2014-04-20.pdf>
  272. for the Aggregated Reduction Method & sample code.
  273. Algorithm by Krzysztof Jankowski, Pierre Laurent - Intel */
  274. #define RED_DECL(a) __m128i H##a##_X##a##_lo, H##a##_X##a##_hi, tmp##a, tmp##a##B
  275. #define RED_SHUFFLE(a) X##a = _mm_shuffle_epi8(X##a, rev)
  276. #define RED_MUL_LOW(a) H##a##_X##a##_lo = _mm_clmulepi64_si128(H##a, X##a, 0x00)
  277. #define RED_MUL_HIGH(a) H##a##_X##a##_hi = _mm_clmulepi64_si128(H##a, X##a, 0x11)
  278. #define RED_MUL_MID(a) \
  279. tmp##a = _mm_shuffle_epi32(H##a, 0x4e); \
  280. tmp##a##B = _mm_shuffle_epi32(X##a, 0x4e); \
  281. tmp##a = _mm_xor_si128(tmp##a, H##a); \
  282. tmp##a##B = _mm_xor_si128(tmp##a##B, X##a); \
  283. tmp##a = _mm_clmulepi64_si128(tmp##a, tmp##a##B, 0x00)
  284. #define MULREDUCE4(rev, H0_, H1_, H2_, H3_, X0_, X1_, X2_, X3_, accv) \
  285. do { \
  286. MAKE4(RED_DECL); \
  287. __m128i lo, hi; \
  288. __m128i tmp8, tmp9; \
  289. __m128i H0 = H0_; \
  290. __m128i H1 = H1_; \
  291. __m128i H2 = H2_; \
  292. __m128i H3 = H3_; \
  293. __m128i X0 = X0_; \
  294. __m128i X1 = X1_; \
  295. __m128i X2 = X2_; \
  296. __m128i X3 = X3_; \
  297. \
  298. /* byte-revert the inputs & xor the first one into the accumulator */ \
  299. \
  300. MAKE4(RED_SHUFFLE); \
  301. X3 = _mm_xor_si128(X3, accv); \
  302. \
  303. /* 4 low H*X (x0*h0) */ \
  304. \
  305. MAKE4(RED_MUL_LOW); \
  306. lo = _mm_xor_si128(H0_X0_lo, H1_X1_lo); \
  307. lo = _mm_xor_si128(lo, H2_X2_lo); \
  308. lo = _mm_xor_si128(lo, H3_X3_lo); \
  309. \
  310. /* 4 high H*X (x1*h1) */ \
  311. \
  312. MAKE4(RED_MUL_HIGH); \
  313. hi = _mm_xor_si128(H0_X0_hi, H1_X1_hi); \
  314. hi = _mm_xor_si128(hi, H2_X2_hi); \
  315. hi = _mm_xor_si128(hi, H3_X3_hi); \
  316. \
  317. /* 4 middle H*X, using Karatsuba, i.e. \
  318. x1*h0+x0*h1 =(x1+x0)*(h1+h0)-x1*h1-x0*h0 \
  319. we already have all x1y1 & x0y0 (accumulated in hi & lo) \
  320. (0 is low half and 1 is high half) \
  321. */ \
  322. /* permute the high and low 64 bits in H1 & X1, \
  323. so create (h0,h1) from (h1,h0) and (x0,x1) from (x1,x0), \
  324. then compute (h0+h1,h1+h0) and (x0+x1,x1+x0), \
  325. and finally multiply \
  326. */ \
  327. MAKE4(RED_MUL_MID); \
  328. \
  329. /* substracts x1*h1 and x0*h0 */ \
  330. tmp0 = _mm_xor_si128(tmp0, lo); \
  331. tmp0 = _mm_xor_si128(tmp0, hi); \
  332. tmp0 = _mm_xor_si128(tmp1, tmp0); \
  333. tmp0 = _mm_xor_si128(tmp2, tmp0); \
  334. tmp0 = _mm_xor_si128(tmp3, tmp0);\
  335. \
  336. /* reduction */ \
  337. tmp0B = _mm_slli_si128(tmp0, 8); \
  338. tmp0 = _mm_srli_si128(tmp0, 8); \
  339. lo = _mm_xor_si128(tmp0B, lo); \
  340. hi = _mm_xor_si128(tmp0, hi); \
  341. tmp3 = lo; \
  342. tmp2B = hi; \
  343. tmp3B = _mm_srli_epi32(tmp3, 31); \
  344. tmp8 = _mm_srli_epi32(tmp2B, 31); \
  345. tmp3 = _mm_slli_epi32(tmp3, 1); \
  346. tmp2B = _mm_slli_epi32(tmp2B, 1); \
  347. tmp9 = _mm_srli_si128(tmp3B, 12); \
  348. tmp8 = _mm_slli_si128(tmp8, 4); \
  349. tmp3B = _mm_slli_si128(tmp3B, 4); \
  350. tmp3 = _mm_or_si128(tmp3, tmp3B); \
  351. tmp2B = _mm_or_si128(tmp2B, tmp8); \
  352. tmp2B = _mm_or_si128(tmp2B, tmp9); \
  353. tmp3B = _mm_slli_epi32(tmp3, 31); \
  354. tmp8 = _mm_slli_epi32(tmp3, 30); \
  355. tmp9 = _mm_slli_epi32(tmp3, 25); \
  356. tmp3B = _mm_xor_si128(tmp3B, tmp8); \
  357. tmp3B = _mm_xor_si128(tmp3B, tmp9); \
  358. tmp8 = _mm_srli_si128(tmp3B, 4); \
  359. tmp3B = _mm_slli_si128(tmp3B, 12); \
  360. tmp3 = _mm_xor_si128(tmp3, tmp3B); \
  361. tmp2 = _mm_srli_epi32(tmp3, 1); \
  362. tmp0B = _mm_srli_epi32(tmp3, 2); \
  363. tmp1B = _mm_srli_epi32(tmp3, 7); \
  364. tmp2 = _mm_xor_si128(tmp2, tmp0B); \
  365. tmp2 = _mm_xor_si128(tmp2, tmp1B); \
  366. tmp2 = _mm_xor_si128(tmp2, tmp8); \
  367. tmp3 = _mm_xor_si128(tmp3, tmp2); \
  368. tmp2B = _mm_xor_si128(tmp2B, tmp3); \
  369. \
  370. accv = tmp2B; \
  371. } while(0)
  372. #define XORx(a) \
  373. temp##a = _mm_xor_si128(temp##a, \
  374. _mm_loadu_si128((const __m128i *) (in + a * 16)))
  375. #define LOADx(a) \
  376. __m128i in##a = _mm_loadu_si128((const __m128i *) (in + a * 16))
  377. /* full encrypt & checksum 8 blocks at once */
  378. #define aesni_encrypt8full(out_, n_, rkeys, in_, accum, hv_, h2v_, h3v_, h4v_, rev) \
  379. do { \
  380. unsigned char *out = out_; \
  381. uint32_t *n = n_; \
  382. const unsigned char *in = in_; \
  383. const __m128i hv = hv_; \
  384. const __m128i h2v = h2v_; \
  385. const __m128i h3v = h3v_; \
  386. const __m128i h4v = h4v_; \
  387. const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
  388. __m128i accv_; \
  389. int roundctr; \
  390. \
  391. MAKE8(NVDECLx); \
  392. MAKE8(TEMPDECLx); \
  393. MAKE8(NVx); \
  394. MAKE8(TEMPx); \
  395. for (roundctr = 1; roundctr < 14; roundctr++) { \
  396. MAKE8(AESENCx); \
  397. } \
  398. MAKE8(AESENCLASTx); \
  399. MAKE8(XORx); \
  400. MAKE8(STOREx); \
  401. accv_ = _mm_load_si128((const __m128i *) accum); \
  402. MULREDUCE4(rev, hv, h2v, h3v, h4v, temp3, temp2, temp1, temp0, accv_); \
  403. MULREDUCE4(rev, hv, h2v, h3v, h4v, temp7, temp6, temp5, temp4, accv_); \
  404. _mm_store_si128((__m128i *) accum, accv_); \
  405. } while(0)
  406. /* checksum 8 blocks at once */
  407. #define aesni_addmul8full(in_, accum, hv_, h2v_, h3v_, h4v_, rev) \
  408. do { \
  409. const unsigned char *in = in_; \
  410. const __m128i hv = hv_; \
  411. const __m128i h2v = h2v_; \
  412. const __m128i h3v = h3v_; \
  413. const __m128i h4v = h4v_; \
  414. __m128i accv_; \
  415. \
  416. MAKE8(LOADx); \
  417. accv_ = _mm_load_si128((const __m128i *) accum); \
  418. MULREDUCE4(rev, hv, h2v, h3v, h4v, in3, in2, in1, in0, accv_); \
  419. MULREDUCE4(rev, hv, h2v, h3v, h4v, in7, in6, in5, in4, accv_); \
  420. _mm_store_si128((__m128i *) accum, accv_); \
  421. } while(0)
  422. /* decrypt 8 blocks at once */
  423. #define aesni_decrypt8full(out_, n_, rkeys, in_) \
  424. do { \
  425. unsigned char *out = out_; \
  426. uint32_t *n = n_; \
  427. const unsigned char *in = in_; \
  428. const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
  429. int roundctr; \
  430. \
  431. MAKE8(NVDECLx); \
  432. MAKE8(TEMPDECLx); \
  433. MAKE8(NVx); \
  434. MAKE8(TEMPx); \
  435. for (roundctr = 1; roundctr < 14; roundctr++) { \
  436. MAKE8(AESENCx); \
  437. } \
  438. MAKE8(AESENCLASTx); \
  439. MAKE8(XORx); \
  440. MAKE8(STOREx); \
  441. } while(0)
  442. int
  443. crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_,
  444. const unsigned char *k)
  445. {
  446. aes256gcm_state *ctx = (aes256gcm_state *) (void *) ctx_;
  447. unsigned char *H = ctx->H;
  448. __m128i *rkeys = ctx->rkeys;
  449. __m128i zero = _mm_setzero_si128();
  450. COMPILER_ASSERT((sizeof *ctx_) >= (sizeof *ctx));
  451. aesni_key256_expand(k, rkeys);
  452. aesni_encrypt1(H, zero, rkeys);
  453. return 0;
  454. }
  455. int
  456. crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c,
  457. unsigned char *mac, unsigned long long *maclen_p,
  458. const unsigned char *m, unsigned long long mlen,
  459. const unsigned char *ad, unsigned long long adlen,
  460. const unsigned char *nsec,
  461. const unsigned char *npub,
  462. const crypto_aead_aes256gcm_state *ctx_)
  463. {
  464. const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
  465. const aes256gcm_state *ctx = (const aes256gcm_state *) (const void *) ctx_;
  466. const __m128i *rkeys = ctx->rkeys;
  467. __m128i Hv, H2v, H3v, H4v, accv;
  468. unsigned long long i, j;
  469. unsigned long long adlen_rnd64 = adlen & ~63ULL;
  470. unsigned long long mlen_rnd128 = mlen & ~127ULL;
  471. CRYPTO_ALIGN(16) uint32_t n2[4];
  472. CRYPTO_ALIGN(16) unsigned char H[16];
  473. CRYPTO_ALIGN(16) unsigned char T[16];
  474. CRYPTO_ALIGN(16) unsigned char accum[16];
  475. CRYPTO_ALIGN(16) unsigned char fb[16];
  476. (void) nsec;
  477. memcpy(H, ctx->H, sizeof H);
  478. if (mlen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) {
  479. sodium_misuse(); /* LCOV_EXCL_LINE */
  480. }
  481. memcpy(&n2[0], npub, 3 * 4);
  482. n2[3] = 0x01000000;
  483. aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys);
  484. {
  485. uint64_t x;
  486. x = _bswap64((uint64_t) (8 * adlen));
  487. memcpy(&fb[0], &x, sizeof x);
  488. x = _bswap64((uint64_t) (8 * mlen));
  489. memcpy(&fb[8], &x, sizeof x);
  490. }
  491. /* we store H (and it's power) byte-reverted once and for all */
  492. Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev);
  493. _mm_store_si128((__m128i *) H, Hv);
  494. H2v = mulv(Hv, Hv);
  495. H3v = mulv(H2v, Hv);
  496. H4v = mulv(H3v, Hv);
  497. accv = _mm_setzero_si128();
  498. /* unrolled by 4 GCM (by 8 doesn't improve using MULREDUCE4) */
  499. for (i = 0; i < adlen_rnd64; i += 64) {
  500. __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0));
  501. __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16));
  502. __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32));
  503. __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48));
  504. MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv);
  505. }
  506. _mm_store_si128((__m128i *) accum, accv);
  507. /* GCM remainder loop */
  508. for (i = adlen_rnd64; i < adlen; i += 16) {
  509. unsigned int blocklen = 16;
  510. if (i + (unsigned long long) blocklen > adlen) {
  511. blocklen = (unsigned int) (adlen - i);
  512. }
  513. addmul(accum, ad + i, blocklen, H);
  514. }
  515. /* this only does 8 full blocks, so no fancy bounds checking is necessary*/
  516. #define LOOPRND128 \
  517. do { \
  518. const int iter = 8; \
  519. const int lb = iter * 16; \
  520. \
  521. for (i = 0; i < mlen_rnd128; i += lb) { \
  522. aesni_encrypt8full(c + i, n2, rkeys, m + i, accum, Hv, H2v, H3v, H4v, rev); \
  523. } \
  524. } while(0)
  525. /* remainder loop, with the slower GCM update to accommodate partial blocks */
  526. #define LOOPRMD128 \
  527. do { \
  528. const int iter = 8; \
  529. const int lb = iter * 16; \
  530. \
  531. for (i = mlen_rnd128; i < mlen; i += lb) { \
  532. CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \
  533. unsigned long long mj = lb; \
  534. \
  535. aesni_encrypt8(outni, n2, rkeys); \
  536. if ((i + mj) >= mlen) { \
  537. mj = mlen - i; \
  538. } \
  539. for (j = 0; j < mj; j++) { \
  540. c[i + j] = m[i + j] ^ outni[j]; \
  541. } \
  542. for (j = 0; j < mj; j += 16) { \
  543. unsigned int bl = 16; \
  544. \
  545. if (j + (unsigned long long) bl >= mj) { \
  546. bl = (unsigned int) (mj - j); \
  547. } \
  548. addmul(accum, c + i + j, bl, H); \
  549. } \
  550. } \
  551. } while(0)
  552. n2[3] &= 0x00ffffff;
  553. COUNTER_INC2(n2);
  554. LOOPRND128;
  555. LOOPRMD128;
  556. addmul(accum, fb, 16, H);
  557. for (i = 0; i < 16; ++i) {
  558. mac[i] = T[i] ^ accum[15 - i];
  559. }
  560. if (maclen_p != NULL) {
  561. *maclen_p = 16;
  562. }
  563. return 0;
  564. }
  565. int
  566. crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p,
  567. const unsigned char *m, unsigned long long mlen,
  568. const unsigned char *ad, unsigned long long adlen,
  569. const unsigned char *nsec,
  570. const unsigned char *npub,
  571. const crypto_aead_aes256gcm_state *ctx_)
  572. {
  573. int ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c,
  574. c + mlen, NULL,
  575. m, mlen,
  576. ad, adlen,
  577. nsec, npub, ctx_);
  578. if (clen_p != NULL) {
  579. *clen_p = mlen + crypto_aead_aes256gcm_ABYTES;
  580. }
  581. return ret;
  582. }
  583. int
  584. crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec,
  585. const unsigned char *c, unsigned long long clen,
  586. const unsigned char *mac,
  587. const unsigned char *ad, unsigned long long adlen,
  588. const unsigned char *npub,
  589. const crypto_aead_aes256gcm_state *ctx_)
  590. {
  591. const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
  592. const aes256gcm_state *ctx = (const aes256gcm_state *) (const void *) ctx_;
  593. const __m128i *rkeys = ctx->rkeys;
  594. __m128i Hv, H2v, H3v, H4v, accv;
  595. unsigned long long i, j;
  596. unsigned long long adlen_rnd64 = adlen & ~63ULL;
  597. unsigned long long mlen;
  598. unsigned long long mlen_rnd128;
  599. CRYPTO_ALIGN(16) uint32_t n2[4];
  600. CRYPTO_ALIGN(16) unsigned char H[16];
  601. CRYPTO_ALIGN(16) unsigned char T[16];
  602. CRYPTO_ALIGN(16) unsigned char accum[16];
  603. CRYPTO_ALIGN(16) unsigned char fb[16];
  604. (void) nsec;
  605. if (clen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) {
  606. sodium_misuse(); /* LCOV_EXCL_LINE */
  607. }
  608. mlen = clen;
  609. memcpy(&n2[0], npub, 3 * 4);
  610. n2[3] = 0x01000000;
  611. aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys);
  612. {
  613. uint64_t x;
  614. x = _bswap64((uint64_t)(8 * adlen));
  615. memcpy(&fb[0], &x, sizeof x);
  616. x = _bswap64((uint64_t)(8 * mlen));
  617. memcpy(&fb[8], &x, sizeof x);
  618. }
  619. memcpy(H, ctx->H, sizeof H);
  620. Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev);
  621. _mm_store_si128((__m128i *) H, Hv);
  622. H2v = mulv(Hv, Hv);
  623. H3v = mulv(H2v, Hv);
  624. H4v = mulv(H3v, Hv);
  625. accv = _mm_setzero_si128();
  626. for (i = 0; i < adlen_rnd64; i += 64) {
  627. __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0));
  628. __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16));
  629. __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32));
  630. __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48));
  631. MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv);
  632. }
  633. _mm_store_si128((__m128i *) accum, accv);
  634. for (i = adlen_rnd64; i < adlen; i += 16) {
  635. unsigned int blocklen = 16;
  636. if (i + (unsigned long long) blocklen > adlen) {
  637. blocklen = (unsigned int) (adlen - i);
  638. }
  639. addmul(accum, ad + i, blocklen, H);
  640. }
  641. mlen_rnd128 = mlen & ~127ULL;
  642. #define LOOPACCUMDRND128 \
  643. do { \
  644. const int iter = 8; \
  645. const int lb = iter * 16; \
  646. for (i = 0; i < mlen_rnd128; i += lb) { \
  647. aesni_addmul8full(c + i, accum, Hv, H2v, H3v, H4v, rev); \
  648. } \
  649. } while(0)
  650. #define LOOPDRND128 \
  651. do { \
  652. const int iter = 8; \
  653. const int lb = iter * 16; \
  654. \
  655. for (i = 0; i < mlen_rnd128; i += lb) { \
  656. aesni_decrypt8full(m + i, n2, rkeys, c + i); \
  657. } \
  658. } while(0)
  659. #define LOOPACCUMDRMD128 \
  660. do { \
  661. const int iter = 8; \
  662. const int lb = iter * 16; \
  663. \
  664. for (i = mlen_rnd128; i < mlen; i += lb) { \
  665. unsigned long long mj = lb; \
  666. \
  667. if ((i + mj) >= mlen) { \
  668. mj = mlen - i; \
  669. } \
  670. for (j = 0; j < mj; j += 16) { \
  671. unsigned int bl = 16; \
  672. \
  673. if (j + (unsigned long long) bl >= mj) { \
  674. bl = (unsigned int) (mj - j); \
  675. } \
  676. addmul(accum, c + i + j, bl, H); \
  677. } \
  678. } \
  679. } while(0)
  680. #define LOOPDRMD128 \
  681. do { \
  682. const int iter = 8; \
  683. const int lb = iter * 16; \
  684. \
  685. for (i = mlen_rnd128; i < mlen; i += lb) { \
  686. CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \
  687. unsigned long long mj = lb; \
  688. \
  689. if ((i + mj) >= mlen) { \
  690. mj = mlen - i; \
  691. } \
  692. aesni_encrypt8(outni, n2, rkeys); \
  693. for (j = 0; j < mj; j++) { \
  694. m[i + j] = c[i + j] ^ outni[j]; \
  695. } \
  696. } \
  697. } while(0)
  698. n2[3] &= 0x00ffffff;
  699. COUNTER_INC2(n2);
  700. LOOPACCUMDRND128;
  701. LOOPACCUMDRMD128;
  702. addmul(accum, fb, 16, H);
  703. {
  704. unsigned char d = 0;
  705. for (i = 0; i < 16; i++) {
  706. d |= (mac[i] ^ (T[i] ^ accum[15 - i]));
  707. }
  708. if (d != 0) {
  709. if (m != NULL) {
  710. memset(m, 0, mlen);
  711. }
  712. return -1;
  713. }
  714. if (m == NULL) {
  715. return 0;
  716. }
  717. }
  718. n2[3] = 0U;
  719. COUNTER_INC2(n2);
  720. LOOPDRND128;
  721. LOOPDRMD128;
  722. return 0;
  723. }
  724. int
  725. crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p,
  726. unsigned char *nsec,
  727. const unsigned char *c, unsigned long long clen,
  728. const unsigned char *ad, unsigned long long adlen,
  729. const unsigned char *npub,
  730. const crypto_aead_aes256gcm_state *ctx_)
  731. {
  732. unsigned long long mlen = 0ULL;
  733. int ret = -1;
  734. if (clen >= crypto_aead_aes256gcm_ABYTES) {
  735. ret = crypto_aead_aes256gcm_decrypt_detached_afternm
  736. (m, nsec, c, clen - crypto_aead_aes256gcm_ABYTES,
  737. c + clen - crypto_aead_aes256gcm_ABYTES,
  738. ad, adlen, npub, ctx_);
  739. }
  740. if (mlen_p != NULL) {
  741. if (ret == 0) {
  742. mlen = clen - crypto_aead_aes256gcm_ABYTES;
  743. }
  744. *mlen_p = mlen;
  745. }
  746. return ret;
  747. }
  748. int
  749. crypto_aead_aes256gcm_encrypt_detached(unsigned char *c,
  750. unsigned char *mac,
  751. unsigned long long *maclen_p,
  752. const unsigned char *m,
  753. unsigned long long mlen,
  754. const unsigned char *ad,
  755. unsigned long long adlen,
  756. const unsigned char *nsec,
  757. const unsigned char *npub,
  758. const unsigned char *k)
  759. {
  760. CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx;
  761. crypto_aead_aes256gcm_beforenm(&ctx, k);
  762. return crypto_aead_aes256gcm_encrypt_detached_afternm
  763. (c, mac, maclen_p, m, mlen, ad, adlen, nsec, npub,
  764. (const crypto_aead_aes256gcm_state *) &ctx);
  765. }
  766. int
  767. crypto_aead_aes256gcm_encrypt(unsigned char *c,
  768. unsigned long long *clen_p,
  769. const unsigned char *m,
  770. unsigned long long mlen,
  771. const unsigned char *ad,
  772. unsigned long long adlen,
  773. const unsigned char *nsec,
  774. const unsigned char *npub,
  775. const unsigned char *k)
  776. {
  777. CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx;
  778. int ret;
  779. crypto_aead_aes256gcm_beforenm(&ctx, k);
  780. ret = crypto_aead_aes256gcm_encrypt_afternm
  781. (c, clen_p, m, mlen, ad, adlen, nsec, npub,
  782. (const crypto_aead_aes256gcm_state *) &ctx);
  783. sodium_memzero(&ctx, sizeof ctx);
  784. return ret;
  785. }
  786. int
  787. crypto_aead_aes256gcm_decrypt_detached(unsigned char *m,
  788. unsigned char *nsec,
  789. const unsigned char *c,
  790. unsigned long long clen,
  791. const unsigned char *mac,
  792. const unsigned char *ad,
  793. unsigned long long adlen,
  794. const unsigned char *npub,
  795. const unsigned char *k)
  796. {
  797. CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx;
  798. crypto_aead_aes256gcm_beforenm(&ctx, k);
  799. return crypto_aead_aes256gcm_decrypt_detached_afternm
  800. (m, nsec, c, clen, mac, ad, adlen, npub,
  801. (const crypto_aead_aes256gcm_state *) &ctx);
  802. }
  803. int
  804. crypto_aead_aes256gcm_decrypt(unsigned char *m,
  805. unsigned long long *mlen_p,
  806. unsigned char *nsec,
  807. const unsigned char *c,
  808. unsigned long long clen,
  809. const unsigned char *ad,
  810. unsigned long long adlen,
  811. const unsigned char *npub,
  812. const unsigned char *k)
  813. {
  814. CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx;
  815. int ret;
  816. crypto_aead_aes256gcm_beforenm(&ctx, k);
  817. ret = crypto_aead_aes256gcm_decrypt_afternm
  818. (m, mlen_p, nsec, c, clen, ad, adlen, npub,
  819. (const crypto_aead_aes256gcm_state *) &ctx);
  820. sodium_memzero(&ctx, sizeof ctx);
  821. return ret;
  822. }
  823. int
  824. crypto_aead_aes256gcm_is_available(void)
  825. {
  826. return sodium_runtime_has_pclmul() & sodium_runtime_has_aesni();
  827. }
  828. #else
  829. int
  830. crypto_aead_aes256gcm_encrypt_detached(unsigned char *c,
  831. unsigned char *mac,
  832. unsigned long long *maclen_p,
  833. const unsigned char *m,
  834. unsigned long long mlen,
  835. const unsigned char *ad,
  836. unsigned long long adlen,
  837. const unsigned char *nsec,
  838. const unsigned char *npub,
  839. const unsigned char *k)
  840. {
  841. errno = ENOSYS;
  842. return -1;
  843. }
  844. int
  845. crypto_aead_aes256gcm_encrypt(unsigned char *c, unsigned long long *clen_p,
  846. const unsigned char *m, unsigned long long mlen,
  847. const unsigned char *ad, unsigned long long adlen,
  848. const unsigned char *nsec, const unsigned char *npub,
  849. const unsigned char *k)
  850. {
  851. errno = ENOSYS;
  852. return -1;
  853. }
  854. int
  855. crypto_aead_aes256gcm_decrypt_detached(unsigned char *m,
  856. unsigned char *nsec,
  857. const unsigned char *c,
  858. unsigned long long clen,
  859. const unsigned char *mac,
  860. const unsigned char *ad,
  861. unsigned long long adlen,
  862. const unsigned char *npub,
  863. const unsigned char *k)
  864. {
  865. errno = ENOSYS;
  866. return -1;
  867. }
  868. int
  869. crypto_aead_aes256gcm_decrypt(unsigned char *m, unsigned long long *mlen_p,
  870. unsigned char *nsec, const unsigned char *c,
  871. unsigned long long clen, const unsigned char *ad,
  872. unsigned long long adlen, const unsigned char *npub,
  873. const unsigned char *k)
  874. {
  875. errno = ENOSYS;
  876. return -1;
  877. }
  878. int
  879. crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_,
  880. const unsigned char *k)
  881. {
  882. errno = ENOSYS;
  883. return -1;
  884. }
  885. int
  886. crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c,
  887. unsigned char *mac, unsigned long long *maclen_p,
  888. const unsigned char *m, unsigned long long mlen,
  889. const unsigned char *ad, unsigned long long adlen,
  890. const unsigned char *nsec,
  891. const unsigned char *npub,
  892. const crypto_aead_aes256gcm_state *ctx_)
  893. {
  894. errno = ENOSYS;
  895. return -1;
  896. }
  897. int
  898. crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p,
  899. const unsigned char *m, unsigned long long mlen,
  900. const unsigned char *ad, unsigned long long adlen,
  901. const unsigned char *nsec, const unsigned char *npub,
  902. const crypto_aead_aes256gcm_state *ctx_)
  903. {
  904. errno = ENOSYS;
  905. return -1;
  906. }
  907. int
  908. crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec,
  909. const unsigned char *c, unsigned long long clen,
  910. const unsigned char *mac,
  911. const unsigned char *ad, unsigned long long adlen,
  912. const unsigned char *npub,
  913. const crypto_aead_aes256gcm_state *ctx_)
  914. {
  915. errno = ENOSYS;
  916. return -1;
  917. }
  918. int
  919. crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p,
  920. unsigned char *nsec,
  921. const unsigned char *c, unsigned long long clen,
  922. const unsigned char *ad, unsigned long long adlen,
  923. const unsigned char *npub,
  924. const crypto_aead_aes256gcm_state *ctx_)
  925. {
  926. errno = ENOSYS;
  927. return -1;
  928. }
  929. int
  930. crypto_aead_aes256gcm_is_available(void)
  931. {
  932. return 0;
  933. }
  934. #endif
  935. size_t
  936. crypto_aead_aes256gcm_keybytes(void)
  937. {
  938. return crypto_aead_aes256gcm_KEYBYTES;
  939. }
  940. size_t
  941. crypto_aead_aes256gcm_nsecbytes(void)
  942. {
  943. return crypto_aead_aes256gcm_NSECBYTES;
  944. }
  945. size_t
  946. crypto_aead_aes256gcm_npubbytes(void)
  947. {
  948. return crypto_aead_aes256gcm_NPUBBYTES;
  949. }
  950. size_t
  951. crypto_aead_aes256gcm_abytes(void)
  952. {
  953. return crypto_aead_aes256gcm_ABYTES;
  954. }
  955. size_t
  956. crypto_aead_aes256gcm_statebytes(void)
  957. {
  958. return (sizeof(crypto_aead_aes256gcm_state) + (size_t) 15U) & ~(size_t) 15U;
  959. }
  960. size_t
  961. crypto_aead_aes256gcm_messagebytes_max(void)
  962. {
  963. return crypto_aead_aes256gcm_MESSAGEBYTES_MAX;
  964. }
  965. void
  966. crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES])
  967. {
  968. randombytes_buf(k, crypto_aead_aes256gcm_KEYBYTES);
  969. }