doc: Fix typo.
[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 #undef POLY1305_SYSV_FUNC_ABI
48
49 /* POLY1305_USE_SSE2 indicates whether to compile with AMD64 SSE2 code. */
50 #undef POLY1305_USE_SSE2
51 #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
52     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
53 # define POLY1305_USE_SSE2 1
54 # define POLY1305_SSE2_BLOCKSIZE 32
55 # define POLY1305_SSE2_STATESIZE 248
56 # define POLY1305_SSE2_ALIGNMENT 16
57 # define POLY1305_SYSV_FUNC_ABI 1
58 #endif
59
60
61 /* POLY1305_USE_AVX2 indicates whether to compile with AMD64 AVX2 code. */
62 #undef POLY1305_USE_AVX2
63 #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
64     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
65     defined(ENABLE_AVX2_SUPPORT)
66 # define POLY1305_USE_AVX2 1
67 # define POLY1305_AVX2_BLOCKSIZE 64
68 # define POLY1305_AVX2_STATESIZE 328
69 # define POLY1305_AVX2_ALIGNMENT 32
70 # define POLY1305_SYSV_FUNC_ABI 1
71 #endif
72
73
74 /* POLY1305_USE_NEON indicates whether to enable ARM NEON assembly code. */
75 #undef POLY1305_USE_NEON
76 #if defined(ENABLE_NEON_SUPPORT) && defined(HAVE_ARM_ARCH_V6) && \
77     defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
78     defined(HAVE_GCC_INLINE_ASM_NEON)
79 # define POLY1305_USE_NEON 1
80 # define POLY1305_NEON_BLOCKSIZE 32
81 # define POLY1305_NEON_STATESIZE 128
82 # define POLY1305_NEON_ALIGNMENT 16
83 #endif
84
85
86 /* Largest block-size used in any implementation (optimized implementations
87  * might use block-size multiple of 16). */
88 #ifdef POLY1305_USE_AVX2
89 # define POLY1305_LARGEST_BLOCKSIZE POLY1305_AVX2_BLOCKSIZE
90 #elif defined(POLY1305_USE_NEON)
91 # define POLY1305_LARGEST_BLOCKSIZE POLY1305_NEON_BLOCKSIZE
92 #elif defined(POLY1305_USE_SSE2)
93 # define POLY1305_LARGEST_BLOCKSIZE POLY1305_SSE2_BLOCKSIZE
94 #else
95 # define POLY1305_LARGEST_BLOCKSIZE POLY1305_REF_BLOCKSIZE
96 #endif
97
98 /* Largest state-size used in any implementation. */
99 #ifdef POLY1305_USE_AVX2
100 # define POLY1305_LARGEST_STATESIZE POLY1305_AVX2_STATESIZE
101 #elif defined(POLY1305_USE_NEON)
102 # define POLY1305_LARGEST_STATESIZE POLY1305_NEON_STATESIZE
103 #elif defined(POLY1305_USE_SSE2)
104 # define POLY1305_LARGEST_STATESIZE POLY1305_SSE2_STATESIZE
105 #else
106 # define POLY1305_LARGEST_STATESIZE POLY1305_REF_STATESIZE
107 #endif
108
109 /* Minimum alignment for state pointer passed to implementations. */
110 #ifdef POLY1305_USE_AVX2
111 # define POLY1305_STATE_ALIGNMENT POLY1305_AVX2_ALIGNMENT
112 #elif defined(POLY1305_USE_NEON)
113 # define POLY1305_STATE_ALIGNMENT POLY1305_NEON_ALIGNMENT
114 #elif defined(POLY1305_USE_SSE2)
115 # define POLY1305_STATE_ALIGNMENT POLY1305_SSE2_ALIGNMENT
116 #else
117 # define POLY1305_STATE_ALIGNMENT POLY1305_REF_ALIGNMENT
118 #endif
119
120
121 /* Assembly implementations use SystemV ABI, ABI conversion and additional
122  * stack to store XMM6-XMM15 needed on Win64. */
123 #undef OPS_FUNC_ABI
124 #if defined(POLY1305_SYSV_FUNC_ABI) && \
125     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)
126 # define OPS_FUNC_ABI __attribute__((sysv_abi))
127 #else
128 # define OPS_FUNC_ABI
129 #endif
130
131
132 typedef struct poly1305_key_s
133 {
134   byte b[POLY1305_KEYLEN];
135 } poly1305_key_t;
136
137
138 typedef struct poly1305_ops_s
139 {
140   size_t block_size;
141   void (*init_ext) (void *ctx, const poly1305_key_t * key) OPS_FUNC_ABI;
142   unsigned int (*blocks) (void *ctx, const byte * m, size_t bytes) OPS_FUNC_ABI;
143   unsigned int (*finish_ext) (void *ctx, const byte * m, size_t remaining,
144                               byte mac[POLY1305_TAGLEN]) OPS_FUNC_ABI;
145 } poly1305_ops_t;
146
147
148 typedef struct poly1305_context_s
149 {
150   byte state[POLY1305_LARGEST_STATESIZE + POLY1305_STATE_ALIGNMENT];
151   byte buffer[POLY1305_LARGEST_BLOCKSIZE];
152   const poly1305_ops_t *ops;
153   unsigned int leftover;
154 } poly1305_context_t;
155
156
157 gcry_err_code_t _gcry_poly1305_init (poly1305_context_t * ctx, const byte * key,
158                                      size_t keylen);
159
160 void _gcry_poly1305_finish (poly1305_context_t * ctx,
161                             byte mac[POLY1305_TAGLEN]);
162
163 void _gcry_poly1305_update (poly1305_context_t * ctx, const byte * buf,
164                             size_t buflen);
165
166
167 #endif /* G10_POLY1305_INTERNAL_H */