gcm.h 5 KB
Newer Older
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/* gcm.h
 *
 * Galois counter mode, specified by NIST,
 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
 *
 */

/* NOTE: Tentative interface, subject to change. No effort will be
   made to avoid incompatible changes. */

/* nettle, low-level cryptographics library
 *
 * Copyright (C) 2011 Niels Möller
 * Copyright (C) 2011 Katholieke Universiteit Leuven
 * 
 * Contributed by Nikos Mavrogiannopoulos
 *
 * The nettle library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * The nettle library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with the nettle library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA.
 */

#ifndef NETTLE_GCM_H_INCLUDED
#define NETTLE_GCM_H_INCLUDED

37
#include "aes.h"
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
38
39
40
41
42
43
44
45
46
47
48
49
50

#ifdef __cplusplus
extern "C" {
#endif

/* Name mangling */
#define gcm_set_key nettle_gcm_set_key
#define gcm_set_iv nettle_gcm_set_iv
#define gcm_auth nettle_gcm_auth
#define gcm_encrypt nettle_gcm_encrypt
#define gcm_decrypt nettle_gcm_decrypt
#define gcm_digest nettle_gcm_digest

51
52
53
54
55
56
57
#define gcm_aes_set_key nettle_gcm_aes_set_key
#define gcm_aes_set_iv nettle_gcm_aes_set_iv
#define gcm_aes_auth nettle_gcm_aes_auth
#define gcm_aes_encrypt nettle_gcm_aes_encrypt
#define gcm_aes_decrypt nettle_gcm_aes_decrypt
#define gcm_aes_digest nettle_gcm_aes_digest

Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
58
59
60
#define GCM_BLOCK_SIZE 16
#define GCM_IV_SIZE (GCM_BLOCK_SIZE - 4)

Niels Möller's avatar
Niels Möller committed
61
#define GCM_TABLE_BITS 4
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
62

63
64
65
66
/* To make sure that we have proper alignment. */
union gcm_block
{
  uint8_t b[GCM_BLOCK_SIZE];
67
  unsigned long w[GCM_BLOCK_SIZE / sizeof(unsigned long)];
68
69
};

70
71
72
/* Hashing subkey */
struct gcm_key
{
73
  union gcm_block h[1 << GCM_TABLE_BITS];
74
75
76
77
};
  
/* Per-message state, depending on the iv */
struct gcm_ctx {
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
78
  /* Original counter block */
79
  union gcm_block iv;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
80
  /* Updated for each block. */
81
  union gcm_block ctr;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
82
  /* Hashing state */
83
  union gcm_block x;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
84
85
86
87
88
89
90
91
  uint64_t auth_size;
  uint64_t data_size;
};

/* FIXME: Should use const for the cipher context. Then needs const for
   nettle_crypt_func, which also rules out using that abstraction for
   arcfour. */
void
92
gcm_set_key(struct gcm_key *key,
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
93
94
95
	    void *cipher, nettle_crypt_func *f);

void
96
97
gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
	   unsigned length, const uint8_t *iv);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
98
99

void
100
101
gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key,
	 unsigned length, const uint8_t *data);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
102
103

void
104
105
gcm_encrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
	    void *cipher, nettle_crypt_func *f,
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
106
107
108
	    unsigned length, uint8_t *dst, const uint8_t *src);

void
109
110
gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
	    void *cipher, nettle_crypt_func *f,
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
111
112
113
	    unsigned length, uint8_t *dst, const uint8_t *src);

void
114
115
gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
	   void *cipher, nettle_crypt_func *f,
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
116
117
	   unsigned length, uint8_t *digest);

118
119
120
121
122
/* Convenience macrology (not sure how useful it is) */

/* All-in-one context, with cipher, hash subkey, and message state. */
#define GCM_CTX(type) \
{ type cipher; struct gcm_key key; struct gcm_ctx gcm; }
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
123
124
125
126

#define GCM_SET_KEY(ctx, set_key, encrypt, length, data)	\
  do {								\
    (set_key)(&(ctx)->cipher, (length), (data));		\
127
    gcm_set_key(&(ctx)->key, &(ctx)->cipher, (encrypt));	\
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
128
129
130
  } while (0)

#define GCM_AUTH(ctx, encrypt, length, data)	    \
131
  gcm_auth(&(ctx)->gcm, &(ctx)->key, (length), (data))
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
132
133

#define GCM_ENCRYPT(ctx, encrypt, length, dst, src)       \
134
  gcm_encrypt(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher, (encrypt),	\
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
135
136
	      (length), (dst), (src))

137
138
#define GCM_DECRYPT(ctx, encrypt, length, dst, src)       \
  gcm_decrypt(&(ctx)->gcm,  &(ctx)->key, &(ctx)->cipher, (encrypt),	\
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
139
140
	      (length), (dst), (src))

141
142
#define GCM_DIGEST(ctx, encrypt, length, digest)		\
  gcm_digest(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher, (encrypt),		\
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
143
144
145
146
147
148
149
150
151
152
153
154
	     (length), (digest))

struct gcm_aes_ctx GCM_CTX(struct aes_ctx);

void
gcm_aes_set_key(struct gcm_aes_ctx *ctx,
		unsigned length, const uint8_t *key);

void
gcm_aes_set_iv(struct gcm_aes_ctx *ctx,
	       unsigned length, const uint8_t *iv);

155
156
/* FIXME: Rename to gcm_aes_update, for consistency with other hash
   and mac functions? */
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
157
158
159
160
161
162
163
164
165
166
167
168
169
void
gcm_aes_auth(struct gcm_aes_ctx *ctx,
	     unsigned length, const uint8_t *data);

void
gcm_aes_encrypt(struct gcm_aes_ctx *ctx,
		unsigned length, uint8_t *dst, const uint8_t *src);

void
gcm_aes_decrypt(struct gcm_aes_ctx *ctx,
		unsigned length, uint8_t *dst, const uint8_t *src);

void
170
gcm_aes_digest(struct gcm_aes_ctx *ctx, unsigned length, uint8_t *digest);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
171
172
173
174
175
176

#ifdef __cplusplus
}
#endif

#endif /* NETTLE_GCM_H_INCLUDED */