ecc: Fix ec_mulm_25519.
[libgcrypt.git] / cipher / mac-gmac.c
1 /* mac-gmac.c  -  GMAC glue for MAC API
2  * Copyright (C) 2013 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 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #include "g10lib.h"
27 #include "cipher.h"
28 #include "./mac-internal.h"
29
30
31 static int
32 map_mac_algo_to_cipher (int mac_algo)
33 {
34   switch (mac_algo)
35     {
36     default:
37       return GCRY_CIPHER_NONE;
38     case GCRY_MAC_GMAC_AES:
39       return GCRY_CIPHER_AES;
40     case GCRY_MAC_GMAC_CAMELLIA:
41       return GCRY_CIPHER_CAMELLIA128;
42     case GCRY_MAC_GMAC_TWOFISH:
43       return GCRY_CIPHER_TWOFISH;
44     case GCRY_MAC_GMAC_SERPENT:
45       return GCRY_CIPHER_SERPENT128;
46     case GCRY_MAC_GMAC_SEED:
47       return GCRY_CIPHER_SEED;
48     }
49 }
50
51
52 static gcry_err_code_t
53 gmac_open (gcry_mac_hd_t h)
54 {
55   gcry_err_code_t err;
56   gcry_cipher_hd_t hd;
57   int secure = (h->magic == CTX_MAGIC_SECURE);
58   int cipher_algo;
59   unsigned int flags;
60
61   cipher_algo = map_mac_algo_to_cipher (h->spec->algo);
62   flags = (secure ? GCRY_CIPHER_SECURE : 0);
63
64   err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_GCM,
65                                     flags);
66   if (err)
67     return err;
68
69   h->u.gmac.cipher_algo = cipher_algo;
70   h->u.gmac.ctx = hd;
71   return 0;
72 }
73
74
75 static void
76 gmac_close (gcry_mac_hd_t h)
77 {
78   _gcry_cipher_close (h->u.gmac.ctx);
79   h->u.gmac.ctx = NULL;
80 }
81
82
83 static gcry_err_code_t
84 gmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
85 {
86   return _gcry_cipher_setkey (h->u.gmac.ctx, key, keylen);
87 }
88
89
90 static gcry_err_code_t
91 gmac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen)
92 {
93   return _gcry_cipher_setiv (h->u.gmac.ctx, iv, ivlen);
94 }
95
96
97 static gcry_err_code_t
98 gmac_reset (gcry_mac_hd_t h)
99 {
100   return _gcry_cipher_reset (h->u.gmac.ctx);
101 }
102
103
104 static gcry_err_code_t
105 gmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
106 {
107   return _gcry_cipher_authenticate (h->u.gmac.ctx, buf, buflen);
108 }
109
110
111 static gcry_err_code_t
112 gmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
113 {
114   if (*outlen > GCRY_GCM_BLOCK_LEN)
115     *outlen = GCRY_GCM_BLOCK_LEN;
116   return _gcry_cipher_gettag (h->u.gmac.ctx, outbuf, *outlen);
117 }
118
119
120 static gcry_err_code_t
121 gmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
122 {
123   return _gcry_cipher_checktag (h->u.gmac.ctx, buf, buflen);
124 }
125
126
127 static unsigned int
128 gmac_get_maclen (int algo)
129 {
130   (void)algo;
131   return GCRY_GCM_BLOCK_LEN;
132 }
133
134
135 static unsigned int
136 gmac_get_keylen (int algo)
137 {
138   return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo));
139 }
140
141
142 static gcry_mac_spec_ops_t gmac_ops = {
143   gmac_open,
144   gmac_close,
145   gmac_setkey,
146   gmac_setiv,
147   gmac_reset,
148   gmac_write,
149   gmac_read,
150   gmac_verify,
151   gmac_get_maclen,
152   gmac_get_keylen
153 };
154
155
156 #if USE_AES
157 gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = {
158   GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES",
159   &gmac_ops
160 };
161 #endif
162 #if USE_TWOFISH
163 gcry_mac_spec_t _gcry_mac_type_spec_gmac_twofish = {
164   GCRY_MAC_GMAC_TWOFISH, {0, 0}, "GMAC_TWOFISH",
165   &gmac_ops
166 };
167 #endif
168 #if USE_SERPENT
169 gcry_mac_spec_t _gcry_mac_type_spec_gmac_serpent = {
170   GCRY_MAC_GMAC_SERPENT, {0, 0}, "GMAC_SERPENT",
171   &gmac_ops
172 };
173 #endif
174 #if USE_SEED
175 gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed = {
176   GCRY_MAC_GMAC_SEED, {0, 0}, "GMAC_SEED",
177   &gmac_ops
178 };
179 #endif
180 #if USE_CAMELLIA
181 gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia = {
182   GCRY_MAC_GMAC_CAMELLIA, {0, 0}, "GMAC_CAMELLIA",
183   &gmac_ops
184 };
185 #endif