/src/libgcrypt/cipher/mac-gmac.c
Line | Count | Source (jump to first uncovered line) |
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 | 0 | { |
34 | 0 | switch (mac_algo) |
35 | 0 | { |
36 | 0 | default: |
37 | 0 | return GCRY_CIPHER_NONE; |
38 | 0 | case GCRY_MAC_GMAC_AES: |
39 | 0 | return GCRY_CIPHER_AES; |
40 | 0 | case GCRY_MAC_GMAC_CAMELLIA: |
41 | 0 | return GCRY_CIPHER_CAMELLIA128; |
42 | 0 | case GCRY_MAC_GMAC_TWOFISH: |
43 | 0 | return GCRY_CIPHER_TWOFISH; |
44 | 0 | case GCRY_MAC_GMAC_SERPENT: |
45 | 0 | return GCRY_CIPHER_SERPENT128; |
46 | 0 | case GCRY_MAC_GMAC_SEED: |
47 | 0 | return GCRY_CIPHER_SEED; |
48 | 0 | } |
49 | 0 | } |
50 | | |
51 | | |
52 | | static gcry_err_code_t |
53 | | gmac_open (gcry_mac_hd_t h) |
54 | 0 | { |
55 | 0 | gcry_err_code_t err; |
56 | 0 | gcry_cipher_hd_t hd; |
57 | 0 | int secure = (h->magic == CTX_MAC_MAGIC_SECURE); |
58 | 0 | int cipher_algo; |
59 | 0 | unsigned int flags; |
60 | |
|
61 | 0 | cipher_algo = map_mac_algo_to_cipher (h->spec->algo); |
62 | 0 | flags = (secure ? GCRY_CIPHER_SECURE : 0); |
63 | |
|
64 | 0 | err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_GCM, |
65 | 0 | flags); |
66 | 0 | if (err) |
67 | 0 | return err; |
68 | | |
69 | 0 | h->u.gmac.cipher_algo = cipher_algo; |
70 | 0 | h->u.gmac.ctx = hd; |
71 | 0 | return 0; |
72 | 0 | } |
73 | | |
74 | | |
75 | | static void |
76 | | gmac_close (gcry_mac_hd_t h) |
77 | 0 | { |
78 | 0 | _gcry_cipher_close (h->u.gmac.ctx); |
79 | 0 | h->u.gmac.ctx = NULL; |
80 | 0 | } |
81 | | |
82 | | |
83 | | static gcry_err_code_t |
84 | | gmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen) |
85 | 0 | { |
86 | 0 | return _gcry_cipher_setkey (h->u.gmac.ctx, key, keylen); |
87 | 0 | } |
88 | | |
89 | | |
90 | | static gcry_err_code_t |
91 | | gmac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen) |
92 | 0 | { |
93 | 0 | return _gcry_cipher_setiv (h->u.gmac.ctx, iv, ivlen); |
94 | 0 | } |
95 | | |
96 | | |
97 | | static gcry_err_code_t |
98 | | gmac_reset (gcry_mac_hd_t h) |
99 | 0 | { |
100 | 0 | return _gcry_cipher_reset (h->u.gmac.ctx); |
101 | 0 | } |
102 | | |
103 | | |
104 | | static gcry_err_code_t |
105 | | gmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen) |
106 | 0 | { |
107 | 0 | return _gcry_cipher_authenticate (h->u.gmac.ctx, buf, buflen); |
108 | 0 | } |
109 | | |
110 | | |
111 | | static gcry_err_code_t |
112 | | gmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen) |
113 | 0 | { |
114 | 0 | if (*outlen > GCRY_GCM_BLOCK_LEN) |
115 | 0 | *outlen = GCRY_GCM_BLOCK_LEN; |
116 | 0 | return _gcry_cipher_gettag (h->u.gmac.ctx, outbuf, *outlen); |
117 | 0 | } |
118 | | |
119 | | |
120 | | static gcry_err_code_t |
121 | | gmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen) |
122 | 0 | { |
123 | 0 | return _gcry_cipher_checktag (h->u.gmac.ctx, buf, buflen); |
124 | 0 | } |
125 | | |
126 | | |
127 | | static unsigned int |
128 | | gmac_get_maclen (int algo) |
129 | 0 | { |
130 | 0 | (void)algo; |
131 | 0 | return GCRY_GCM_BLOCK_LEN; |
132 | 0 | } |
133 | | |
134 | | |
135 | | static unsigned int |
136 | | gmac_get_keylen (int algo) |
137 | 0 | { |
138 | 0 | return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo)); |
139 | 0 | } |
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 | | NULL, |
154 | | NULL |
155 | | }; |
156 | | |
157 | | |
158 | | #if USE_AES |
159 | | const gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = { |
160 | | GCRY_MAC_GMAC_AES, {0, 0}, "GMAC_AES", |
161 | | &gmac_ops |
162 | | }; |
163 | | #endif |
164 | | #if USE_TWOFISH |
165 | | const gcry_mac_spec_t _gcry_mac_type_spec_gmac_twofish = { |
166 | | GCRY_MAC_GMAC_TWOFISH, {0, 0}, "GMAC_TWOFISH", |
167 | | &gmac_ops |
168 | | }; |
169 | | #endif |
170 | | #if USE_SERPENT |
171 | | const gcry_mac_spec_t _gcry_mac_type_spec_gmac_serpent = { |
172 | | GCRY_MAC_GMAC_SERPENT, {0, 0}, "GMAC_SERPENT", |
173 | | &gmac_ops |
174 | | }; |
175 | | #endif |
176 | | #if USE_SEED |
177 | | const gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed = { |
178 | | GCRY_MAC_GMAC_SEED, {0, 0}, "GMAC_SEED", |
179 | | &gmac_ops |
180 | | }; |
181 | | #endif |
182 | | #if USE_CAMELLIA |
183 | | const gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia = { |
184 | | GCRY_MAC_GMAC_CAMELLIA, {0, 0}, "GMAC_CAMELLIA", |
185 | | &gmac_ops |
186 | | }; |
187 | | #endif |