gcm.h 8.11 KB
Newer Older
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
1 2 3 4 5 6 7 8 9 10
/* gcm.h
 *
 * Galois counter mode, specified by NIST,
 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
 *
 */

/* nettle, low-level cryptographics library
 *
 * Copyright (C) 2011 Katholieke Universiteit Leuven
Niels Möller's avatar
Niels Möller committed
11
 * Copyright (C) 2011, 2014 Niels Möller
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 * 
 * 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
27 28
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02111-1301, USA.
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
29 30 31 32 33
 */

#ifndef NETTLE_GCM_H_INCLUDED
#define NETTLE_GCM_H_INCLUDED

34
#include "aes.h"
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
35 36 37 38 39 40 41 42

#ifdef __cplusplus
extern "C" {
#endif

/* Name mangling */
#define gcm_set_key nettle_gcm_set_key
#define gcm_set_iv nettle_gcm_set_iv
43
#define gcm_update nettle_gcm_update
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
44 45 46 47
#define gcm_encrypt nettle_gcm_encrypt
#define gcm_decrypt nettle_gcm_decrypt
#define gcm_digest nettle_gcm_digest

Niels Möller's avatar
Niels Möller committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
#define gcm_aes128_set_key nettle_gcm_aes128_set_key
#define gcm_aes128_set_iv nettle_gcm_aes128_set_iv
#define gcm_aes128_update nettle_gcm_aes128_update
#define gcm_aes128_encrypt nettle_gcm_aes128_encrypt
#define gcm_aes128_decrypt nettle_gcm_aes128_decrypt
#define gcm_aes128_digest nettle_gcm_aes128_digest

#define gcm_aes192_set_key nettle_gcm_aes192_set_key
#define gcm_aes192_set_iv nettle_gcm_aes192_set_iv
#define gcm_aes192_update nettle_gcm_aes192_update
#define gcm_aes192_encrypt nettle_gcm_aes192_encrypt
#define gcm_aes192_decrypt nettle_gcm_aes192_decrypt
#define gcm_aes192_digest nettle_gcm_aes192_digest

#define gcm_aes256_set_key nettle_gcm_aes256_set_key
#define gcm_aes256_set_iv nettle_gcm_aes256_set_iv
#define gcm_aes256_update nettle_gcm_aes256_update
#define gcm_aes256_encrypt nettle_gcm_aes256_encrypt
#define gcm_aes256_decrypt nettle_gcm_aes256_decrypt
#define gcm_aes256_digest nettle_gcm_aes256_digest

69 70
#define gcm_aes_set_key nettle_gcm_aes_set_key
#define gcm_aes_set_iv nettle_gcm_aes_set_iv
71
#define gcm_aes_update nettle_gcm_aes_update
72 73 74 75
#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
76 77 78
#define GCM_BLOCK_SIZE 16
#define GCM_IV_SIZE (GCM_BLOCK_SIZE - 4)

79
#define GCM_TABLE_BITS 8
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
80

81 82 83
/* Hashing subkey */
struct gcm_key
{
Niels Möller's avatar
Niels Möller committed
84
  union nettle_block16 h[1 << GCM_TABLE_BITS];
85
};
Niels Möller's avatar
Niels Möller committed
86

87 88
/* Per-message state, depending on the iv */
struct gcm_ctx {
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
89
  /* Original counter block */
Niels Möller's avatar
Niels Möller committed
90
  union nettle_block16 iv;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
91
  /* Updated for each block. */
Niels Möller's avatar
Niels Möller committed
92
  union nettle_block16 ctr;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
93
  /* Hashing state */
Niels Möller's avatar
Niels Möller committed
94
  union nettle_block16 x;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
95 96 97 98 99 100 101 102
  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
103
gcm_set_key(struct gcm_key *key,
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
104 105 106
	    void *cipher, nettle_crypt_func *f);

void
107
gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
108
	   size_t length, const uint8_t *iv);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
109 110

void
111
gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key,
112
	   size_t length, const uint8_t *data);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
113 114

void
115 116
gcm_encrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
	    void *cipher, nettle_crypt_func *f,
117
	    size_t length, uint8_t *dst, const uint8_t *src);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
118 119

void
120 121
gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
	    void *cipher, nettle_crypt_func *f,
122
	    size_t length, uint8_t *dst, const uint8_t *src);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
123 124

void
125 126
gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
	   void *cipher, nettle_crypt_func *f,
127
	   size_t length, uint8_t *digest);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
128

129
/* Convenience macrology (not sure how useful it is) */
Niels Möller's avatar
Niels Möller committed
130
/* All-in-one context, with hash subkey, message state, and cipher. */
131
#define GCM_CTX(type) \
Niels Möller's avatar
Niels Möller committed
132
  { struct gcm_key key; struct gcm_ctx gcm; type cipher; }
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
133

134
/* NOTE: Avoid using NULL, as we don't include anything defining it. */
135
#define GCM_SET_KEY(ctx, set_key, encrypt, key)			\
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
136
  do {								\
137
    (set_key)(&(ctx)->cipher, (key));				\
138 139 140
    if (0) (encrypt)(&(ctx)->cipher, 0, (void *)0, (void *)0);	\
    gcm_set_key(&(ctx)->key, &(ctx)->cipher,			\
		(nettle_crypt_func *) (encrypt));		\
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
141 142
  } while (0)

143 144
#define GCM_SET_IV(ctx, length, data)				\
  gcm_set_iv(&(ctx)->gcm, &(ctx)->key, (length), (data))
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
145

146 147
#define GCM_UPDATE(ctx, length, data)			\
  gcm_update(&(ctx)->gcm, &(ctx)->key, (length), (data))
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
148

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
#define GCM_ENCRYPT(ctx, encrypt, length, dst, src)			\
  (0 ? (encrypt)(&(ctx)->cipher, 0, (void *)0, (void *)0)		\
     : gcm_encrypt(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher,		\
		   (nettle_crypt_func *) (encrypt),			\
		   (length), (dst), (src)))

#define GCM_DECRYPT(ctx, encrypt, length, dst, src)			\
  (0 ? (encrypt)(&(ctx)->cipher, 0, (void *)0, (void *)0)		\
     : gcm_decrypt(&(ctx)->gcm,  &(ctx)->key, &(ctx)->cipher,		\
		   (nettle_crypt_func *) (encrypt),			\
		   (length), (dst), (src)))

#define GCM_DIGEST(ctx, encrypt, length, digest)			\
  (0 ? (encrypt)(&(ctx)->cipher, 0, (void *)0, (void *)0)		\
     : gcm_digest(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher,		\
		  (nettle_crypt_func *) (encrypt),			\
		  (length), (digest)))
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
166

Niels Möller's avatar
Niels Möller committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
struct gcm_aes128_ctx GCM_CTX(struct aes128_ctx);

void
gcm_aes128_set_key(struct gcm_aes128_ctx *ctx,
		   size_t length, const uint8_t *key);

/* FIXME: Define _update and _set_iv as some kind of aliaes,
   there's nothing aes-specific. */
void
gcm_aes128_update (struct gcm_aes128_ctx *ctx,
		   size_t length, const uint8_t *data);
void
gcm_aes128_set_iv (struct gcm_aes128_ctx *ctx,
		   size_t length, const uint8_t *iv);

void
gcm_aes128_encrypt(struct gcm_aes128_ctx *ctx,
		   size_t length, uint8_t *dst, const uint8_t *src);

void
gcm_aes128_decrypt(struct gcm_aes128_ctx *ctx,
		   size_t length, uint8_t *dst, const uint8_t *src);

void
gcm_aes128_digest(struct gcm_aes128_ctx *ctx,
		  size_t length, uint8_t *digest);

struct gcm_aes192_ctx GCM_CTX(struct aes192_ctx);

void
gcm_aes192_set_key(struct gcm_aes192_ctx *ctx,
		   size_t length, const uint8_t *key);

void
gcm_aes192_update (struct gcm_aes192_ctx *ctx,
		   size_t length, const uint8_t *data);
void
gcm_aes192_set_iv (struct gcm_aes192_ctx *ctx,
		   size_t length, const uint8_t *iv);

void
gcm_aes192_encrypt(struct gcm_aes192_ctx *ctx,
		   size_t length, uint8_t *dst, const uint8_t *src);

void
gcm_aes192_decrypt(struct gcm_aes192_ctx *ctx,
		   size_t length, uint8_t *dst, const uint8_t *src);

void
gcm_aes192_digest(struct gcm_aes192_ctx *ctx,
		  size_t length, uint8_t *digest);

struct gcm_aes256_ctx GCM_CTX(struct aes256_ctx);

void
gcm_aes256_set_key(struct gcm_aes256_ctx *ctx,
		   size_t length, const uint8_t *key);

void
gcm_aes256_update (struct gcm_aes256_ctx *ctx,
		   size_t length, const uint8_t *data);
void
gcm_aes256_set_iv (struct gcm_aes256_ctx *ctx,
		   size_t length, const uint8_t *iv);

void
gcm_aes256_encrypt(struct gcm_aes256_ctx *ctx,
		   size_t length, uint8_t *dst, const uint8_t *src);

void
gcm_aes256_decrypt(struct gcm_aes256_ctx *ctx,
		   size_t length, uint8_t *dst, const uint8_t *src);

void
gcm_aes256_digest(struct gcm_aes256_ctx *ctx,
		  size_t length, uint8_t *digest);

/* Old aes interface, for backwards compatibility */
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
245 246 247 248
struct gcm_aes_ctx GCM_CTX(struct aes_ctx);

void
gcm_aes_set_key(struct gcm_aes_ctx *ctx,
249
		size_t length, const uint8_t *key);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
250 251 252

void
gcm_aes_set_iv(struct gcm_aes_ctx *ctx,
253
	       size_t length, const uint8_t *iv);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
254 255

void
256
gcm_aes_update(struct gcm_aes_ctx *ctx,
257
	       size_t length, const uint8_t *data);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
258 259 260

void
gcm_aes_encrypt(struct gcm_aes_ctx *ctx,
261
		size_t length, uint8_t *dst, const uint8_t *src);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
262 263 264

void
gcm_aes_decrypt(struct gcm_aes_ctx *ctx,
265
		size_t length, uint8_t *dst, const uint8_t *src);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
266 267

void
268
gcm_aes_digest(struct gcm_aes_ctx *ctx, size_t length, uint8_t *digest);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
269 270 271 272 273 274

#ifdef __cplusplus
}
#endif

#endif /* NETTLE_GCM_H_INCLUDED */