Line data Source code
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 38 : map_mac_algo_to_cipher (int mac_algo)
33 : {
34 38 : switch (mac_algo)
35 : {
36 : default:
37 0 : return GCRY_CIPHER_NONE;
38 : case GCRY_MAC_GMAC_AES:
39 22 : return GCRY_CIPHER_AES;
40 : case GCRY_MAC_GMAC_CAMELLIA:
41 4 : return GCRY_CIPHER_CAMELLIA128;
42 : case GCRY_MAC_GMAC_TWOFISH:
43 4 : return GCRY_CIPHER_TWOFISH;
44 : case GCRY_MAC_GMAC_SERPENT:
45 4 : return GCRY_CIPHER_SERPENT128;
46 : case GCRY_MAC_GMAC_SEED:
47 4 : return GCRY_CIPHER_SEED;
48 : }
49 : }
50 :
51 :
52 : static gcry_err_code_t
53 28 : gmac_open (gcry_mac_hd_t h)
54 : {
55 : gcry_err_code_t err;
56 : gcry_cipher_hd_t hd;
57 28 : int secure = (h->magic == CTX_MAGIC_SECURE);
58 : int cipher_algo;
59 : unsigned int flags;
60 :
61 28 : cipher_algo = map_mac_algo_to_cipher (h->spec->algo);
62 28 : flags = (secure ? GCRY_CIPHER_SECURE : 0);
63 :
64 28 : err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_GCM,
65 : flags);
66 28 : if (err)
67 0 : return err;
68 :
69 28 : h->u.gmac.cipher_algo = cipher_algo;
70 28 : h->u.gmac.ctx = hd;
71 28 : return 0;
72 : }
73 :
74 :
75 : static void
76 28 : gmac_close (gcry_mac_hd_t h)
77 : {
78 28 : _gcry_cipher_close (h->u.gmac.ctx);
79 28 : h->u.gmac.ctx = NULL;
80 28 : }
81 :
82 :
83 : static gcry_err_code_t
84 28 : gmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
85 : {
86 28 : return _gcry_cipher_setkey (h->u.gmac.ctx, key, keylen);
87 : }
88 :
89 :
90 : static gcry_err_code_t
91 16 : gmac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen)
92 : {
93 16 : return _gcry_cipher_setiv (h->u.gmac.ctx, iv, ivlen);
94 : }
95 :
96 :
97 : static gcry_err_code_t
98 4480 : gmac_reset (gcry_mac_hd_t h)
99 : {
100 4480 : return _gcry_cipher_reset (h->u.gmac.ctx);
101 : }
102 :
103 :
104 : static gcry_err_code_t
105 564050 : gmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
106 : {
107 564050 : return _gcry_cipher_authenticate (h->u.gmac.ctx, buf, buflen);
108 : }
109 :
110 :
111 : static gcry_err_code_t
112 4503 : gmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
113 : {
114 4503 : if (*outlen > GCRY_GCM_BLOCK_LEN)
115 0 : *outlen = GCRY_GCM_BLOCK_LEN;
116 4503 : return _gcry_cipher_gettag (h->u.gmac.ctx, outbuf, *outlen);
117 : }
118 :
119 :
120 : static gcry_err_code_t
121 18 : gmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
122 : {
123 18 : return _gcry_cipher_checktag (h->u.gmac.ctx, buf, buflen);
124 : }
125 :
126 :
127 : static unsigned int
128 23 : gmac_get_maclen (int algo)
129 : {
130 : (void)algo;
131 23 : return GCRY_GCM_BLOCK_LEN;
132 : }
133 :
134 :
135 : static unsigned int
136 10 : gmac_get_keylen (int algo)
137 : {
138 10 : 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
|