rijndael: refactor to reduce number of #ifdefs and branches
[libgcrypt.git] / cipher / poly1305-internal.h
1 /* poly1305-internal.h  -  Poly1305 internals
2  * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifndef G10_POLY1305_INTERNAL_H
21 #define G10_POLY1305_INTERNAL_H
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "types.h"
28 #include "g10lib.h"
29 #include "cipher.h"
30 #include "bufhelp.h"
31
32
33 #define POLY1305_TAGLEN 16
34 #define POLY1305_KEYLEN 32
35
36
37 /* Block-size used in default implementation. */
38 #define POLY1305_REF_BLOCKSIZE 16
39
40 /* State size of default implementation. */
41 #define POLY1305_REF_STATESIZE 64
42
43 /* State alignment for default implementation. */
44 #define POLY1305_REF_ALIGNMENT sizeof(void *)
45
46
47 /* POLY1305_USE_SSE2 indicates whether to compile with AMD64 SSE2 code. */
48 #undef POLY1305_USE_SSE2
49 #if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
50 # define POLY1305_USE_SSE2 1
51 # define POLY1305_SSE2_BLOCKSIZE 32
52 # define POLY1305_SSE2_STATESIZE 248
53 # define POLY1305_SSE2_ALIGNMENT 16
54 #endif
55
56
57 /* POLY1305_USE_AVX2 indicates whether to compile with AMD64 AVX2 code. */
58 #undef POLY1305_USE_AVX2
59 #if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
60     defined(ENABLE_AVX2_SUPPORT)
61 # define POLY1305_USE_AVX2 1
62 # define POLY1305_AVX2_BLOCKSIZE 64
63 # define POLY1305_AVX2_STATESIZE 328
64 # define POLY1305_AVX2_ALIGNMENT 32
65 #endif
66
67
68 /* POLY1305_USE_NEON indicates whether to enable ARM NEON assembly code. */
69 #undef POLY1305_USE_NEON
70 #if defined(ENABLE_NEON_SUPPORT) && defined(HAVE_ARM_ARCH_V6) && \
71     defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
72     defined(HAVE_GCC_INLINE_ASM_NEON)
73 # define POLY1305_USE_NEON 1
74 # define POLY1305_NEON_BLOCKSIZE 32
75 # define POLY1305_NEON_STATESIZE 128
76 # define POLY1305_NEON_ALIGNMENT 16
77 #endif
78
79
80 /* Largest block-size used in any implementation (optimized implementations
81  * might use block-size multiple of 16). */
82 #ifdef POLY1305_USE_AVX2
83 # define POLY1305_LARGEST_BLOCKSIZE POLY1305_AVX2_BLOCKSIZE
84 #elif defined(POLY1305_USE_NEON)
85 # define POLY1305_LARGEST_BLOCKSIZE POLY1305_NEON_BLOCKSIZE
86 #elif defined(POLY1305_USE_SSE2)
87 # define POLY1305_LARGEST_BLOCKSIZE POLY1305_SSE2_BLOCKSIZE
88 #else
89 # define POLY1305_LARGEST_BLOCKSIZE POLY1305_REF_BLOCKSIZE
90 #endif
91
92 /* Largest state-size used in any implementation. */
93 #ifdef POLY1305_USE_AVX2
94 # define POLY1305_LARGEST_STATESIZE POLY1305_AVX2_STATESIZE
95 #elif defined(POLY1305_USE_NEON)
96 # define POLY1305_LARGEST_STATESIZE POLY1305_NEON_STATESIZE
97 #elif defined(POLY1305_USE_SSE2)
98 # define POLY1305_LARGEST_STATESIZE POLY1305_SSE2_STATESIZE
99 #else
100 # define POLY1305_LARGEST_STATESIZE POLY1305_REF_STATESIZE
101 #endif
102
103 /* Minimum alignment for state pointer passed to implementations. */
104 #ifdef POLY1305_USE_AVX2
105 # define POLY1305_STATE_ALIGNMENT POLY1305_AVX2_ALIGNMENT
106 #elif defined(POLY1305_USE_NEON)
107 # define POLY1305_STATE_ALIGNMENT POLY1305_NEON_ALIGNMENT
108 #elif defined(POLY1305_USE_SSE2)
109 # define POLY1305_STATE_ALIGNMENT POLY1305_SSE2_ALIGNMENT
110 #else
111 # define POLY1305_STATE_ALIGNMENT POLY1305_REF_ALIGNMENT
112 #endif
113
114
115 typedef struct poly1305_key_s
116 {
117   byte b[POLY1305_KEYLEN];
118 } poly1305_key_t;
119
120
121 typedef struct poly1305_ops_s
122 {
123   size_t block_size;
124   void (*init_ext) (void *ctx, const poly1305_key_t * key);
125   unsigned int (*blocks) (void *ctx, const byte * m, size_t bytes);
126   unsigned int (*finish_ext) (void *ctx, const byte * m, size_t remaining,
127                               byte mac[POLY1305_TAGLEN]);
128 } poly1305_ops_t;
129
130
131 typedef struct poly1305_context_s
132 {
133   byte state[POLY1305_LARGEST_STATESIZE + POLY1305_STATE_ALIGNMENT];
134   byte buffer[POLY1305_LARGEST_BLOCKSIZE];
135   const poly1305_ops_t *ops;
136   unsigned int leftover;
137 } poly1305_context_t;
138
139
140 gcry_err_code_t _gcry_poly1305_init (poly1305_context_t * ctx, const byte * key,
141                                      size_t keylen);
142
143 void _gcry_poly1305_finish (poly1305_context_t * ctx,
144                             byte mac[POLY1305_TAGLEN]);
145
146 void _gcry_poly1305_update (poly1305_context_t * ctx, const byte * buf,
147                             size_t buflen);
148
149
150 #endif /* G10_POLY1305_INTERNAL_H */