gcm.h 5.3 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
/* 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
30 31
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02111-1301, USA.
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
32 33 34 35 36
 */

#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

#ifdef __cplusplus
extern "C" {
#endif

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

51 52
#define gcm_aes_set_key nettle_gcm_aes_set_key
#define gcm_aes_set_iv nettle_gcm_aes_set_iv
53
#define gcm_aes_update nettle_gcm_aes_update
54 55 56 57
#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)

61
#define GCM_TABLE_BITS 8
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
62

63 64 65
/* Hashing subkey */
struct gcm_key
{
Niels Möller's avatar
Niels Möller committed
66
  union nettle_block16 h[1 << GCM_TABLE_BITS];
67 68 69 70
};
  
/* Per-message state, depending on the iv */
struct gcm_ctx {
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
71
  /* Original counter block */
Niels Möller's avatar
Niels Möller committed
72
  union nettle_block16 iv;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
73
  /* Updated for each block. */
Niels Möller's avatar
Niels Möller committed
74
  union nettle_block16 ctr;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
75
  /* Hashing state */
Niels Möller's avatar
Niels Möller committed
76
  union nettle_block16 x;
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
77 78 79 80 81 82 83 84
  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
85
gcm_set_key(struct gcm_key *key,
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
86 87 88
	    void *cipher, nettle_crypt_func *f);

void
89
gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
90
	   size_t length, const uint8_t *iv);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
91 92

void
93
gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key,
94
	   size_t length, const uint8_t *data);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
95 96

void
97 98
gcm_encrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
	    void *cipher, nettle_crypt_func *f,
99
	    size_t length, uint8_t *dst, const uint8_t *src);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
100 101

void
102 103
gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
	    void *cipher, nettle_crypt_func *f,
104
	    size_t length, uint8_t *dst, const uint8_t *src);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
105 106

void
107 108
gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
	   void *cipher, nettle_crypt_func *f,
109
	   size_t length, uint8_t *digest);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
110

111 112 113 114 115
/* 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
116

117
/* NOTE: Avoid using NULL, as we don't include anything defining it. */
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
118 119 120
#define GCM_SET_KEY(ctx, set_key, encrypt, length, data)	\
  do {								\
    (set_key)(&(ctx)->cipher, (length), (data));		\
121 122 123
    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
124 125
  } while (0)

126 127
#define GCM_SET_IV(ctx, length, data)				\
  gcm_set_iv(&(ctx)->gcm, &(ctx)->key, (length), (data))
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
128

129 130
#define GCM_UPDATE(ctx, length, data)			\
  gcm_update(&(ctx)->gcm, &(ctx)->key, (length), (data))
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
131

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
#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
149 150 151 152 153

struct gcm_aes_ctx GCM_CTX(struct aes_ctx);

void
gcm_aes_set_key(struct gcm_aes_ctx *ctx,
154
		size_t length, const uint8_t *key);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
155 156 157

void
gcm_aes_set_iv(struct gcm_aes_ctx *ctx,
158
	       size_t length, const uint8_t *iv);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
159 160

void
161
gcm_aes_update(struct gcm_aes_ctx *ctx,
162
	       size_t length, const uint8_t *data);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
163 164 165

void
gcm_aes_encrypt(struct gcm_aes_ctx *ctx,
166
		size_t length, uint8_t *dst, const uint8_t *src);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
167 168 169

void
gcm_aes_decrypt(struct gcm_aes_ctx *ctx,
170
		size_t length, uint8_t *dst, const uint8_t *src);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
171 172

void
173
gcm_aes_digest(struct gcm_aes_ctx *ctx, size_t length, uint8_t *digest);
Nikos Mavrogiannopoulos's avatar
Nikos Mavrogiannopoulos committed
174 175 176 177 178 179

#ifdef __cplusplus
}
#endif

#endif /* NETTLE_GCM_H_INCLUDED */