summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.h
blob: 2ee7f467811215553bbfa5177ceada6c78055d1b (plain)
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * cifra - embedded cryptography library
 * Written in 2014 by Joseph Birr-Pixton <jpixton@gmail.com>
 *
 * To the extent possible under law, the author(s) have dedicated all
 * copyright and related and neighboring rights to this software to the
 * public domain worldwide. This software is distributed without any
 * warranty.
 *
 * You should have received a copy of the CC0 Public Domain Dedication
 * along with this software. If not, see
 * <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

/**
 * The AES block cipher
 * ====================
 *
 * This is a small, simple implementation of AES.  Key expansion is done
 * first, filling in a :c:type:`cf_aes_context`.  Then encryption and
 * decryption can be performed as desired.
 *
 * Usually you don't want to use AES directly; you should use it via
 * a :doc:`block cipher mode <modes>`.
 */

#ifndef AES_H
#define AES_H

#include <stddef.h>
#include <stdint.h>

#include "prp.h"

/* .. c:macro:: AES_BLOCKSZ
 * AES has a 128-bit block size.  This quantity is in bytes.
 */
#define AES_BLOCKSZ 16

/* --- Size configuration --- */

/* .. c:macro:: AES128_ROUNDS
 * .. c:macro:: AES192_ROUNDS
 * .. c:macro:: AES256_ROUNDS
 *
 * Round counts for different key sizes.
 */
#define AES128_ROUNDS 10
#define AES192_ROUNDS 12
#define AES256_ROUNDS 14

/* .. c:macro:: CF_AES_MAXROUNDS
 *
 * You can reduce the maximum number of rounds this implementation
 * supports. This reduces the storage needed by :c:type:`cf_aes_context`.
 *
 * The default is :c:macro:`AES256_ROUNDS` and is good for all key
 * sizes.
 */
#ifndef CF_AES_MAXROUNDS
# define CF_AES_MAXROUNDS AES256_ROUNDS
#endif

/* .. c:macro:: CF_AES_ENCRYPT_ONLY
 *
 * Define this to 1 if you don't need to decrypt anything.
 * This saves space.  :c:func:`cf_aes_decrypt` calls `abort(3)`.
 */
#ifndef CF_AES_ENCRYPT_ONLY
# define CF_AES_ENCRYPT_ONLY 0
#endif

/* .. c:type:: cf_aes_context
 * This type represents an expanded AES key.  Create one
 * using :c:func:`cf_aes_init`, make use of one using
 * :c:func:`cf_aes_encrypt` or :c:func:`cf_aes_decrypt`.
 *
 * The contents of this structure are equivalent to the
 * original key material.  You should clean the
 * contents of this structure with :c:func:`cf_aes_finish`
 * when you're done.
 *
 * .. c:member:: cf_aes_context.rounds
 * 
 * Number of rounds to use, set by :c:func:`cf_aes_init`.
 *
 * This depends on the original key size, and will be
 * :c:macro:`AES128_ROUNDS`, :c:macro:`AES192_ROUNDS` or
 * :c:macro:`AES256_ROUNDS`.
 *
 * .. c:member:: cf_aes_context.ks
 * 
 * Expanded key material.  Filled in by :c:func:`cf_aes_init`.
 */
typedef struct
{
  uint32_t rounds;
  uint32_t ks[AES_BLOCKSZ / 4 * (CF_AES_MAXROUNDS + 1)];
} cf_aes_context;

/* .. c:function:: $DECL
 * This function does AES key expansion.  It destroys
 * existing contents of :c:data:`ctx`.
 *
 * :param ctx: expanded key context, filled in by this function.
 * :param key: pointer to key material, of :c:data:`nkey` bytes.
 * :param nkey: length of key material. Must be `16`, `24` or `32`.
 */
extern void cf_aes_init(cf_aes_context *ctx,
                        const uint8_t *key,
                        size_t nkey);

/* .. c:function:: $DECL
 * Encrypts the given block, from :c:data:`in` to :c:data:`out`.
 * These may alias.
 *
 * Fails at runtime if :c:data:`ctx` is invalid.
 *
 * :param ctx: expanded key context
 * :param in: input block (read)
 * :param out: output block (written)
 */
extern void cf_aes_encrypt(const cf_aes_context *ctx,
                           const uint8_t in[AES_BLOCKSZ],
                           uint8_t out[AES_BLOCKSZ]);

/* .. c:function:: $DECL
 * Decrypts the given block, from :c:data:`in` to :c:data:`out`.
 * These may alias.
 *
 * Fails at runtime if :c:data:`ctx` is invalid.
 *
 * :param ctx: expanded key context
 * :param in: input block (read)
 * :param out: output block (written)
 */
extern void cf_aes_decrypt(const cf_aes_context *ctx,
                           const uint8_t in[AES_BLOCKSZ],
                           uint8_t out[AES_BLOCKSZ]);

/* .. c:function:: $DECL
 * Erase scheduled key material.
 *
 * Call this when you're done to erase the round keys. */
extern void cf_aes_finish(cf_aes_context *ctx);

/* .. c:var:: const cf_prp cf_aes
 * Abstract interface to AES.  See :c:type:`cf_prp` for
 * more information. */
extern const cf_prp cf_aes;

#endif