Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/crypto/aes-cbc-macs.h
170831 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
/*
3
* Support for AES-CMAC, AES-XCBC-MAC, and AES-CBC-MAC
4
*
5
* Copyright 2026 Google LLC
6
*/
7
#ifndef _CRYPTO_AES_CBC_MACS_H
8
#define _CRYPTO_AES_CBC_MACS_H
9
10
#include <crypto/aes.h>
11
12
/**
13
* struct aes_cmac_key - Prepared key for AES-CMAC or AES-XCBC-MAC
14
* @aes: The AES key for cipher block chaining
15
* @k_final: Finalization subkeys for the final block.
16
* k_final[0] (CMAC K1, XCBC-MAC K2) is used if it's a full block.
17
* k_final[1] (CMAC K2, XCBC-MAC K3) is used if it's a partial block.
18
*/
19
struct aes_cmac_key {
20
struct aes_enckey aes;
21
union {
22
u8 b[AES_BLOCK_SIZE];
23
__be64 w[2];
24
} k_final[2];
25
};
26
27
/**
28
* struct aes_cmac_ctx - Context for computing an AES-CMAC or AES-XCBC-MAC value
29
* @key: Pointer to the key struct. A pointer is used rather than a copy of the
30
* struct, since the key struct size may be large. It is assumed that the
31
* key lives at least as long as the context.
32
* @partial_len: Number of bytes that have been XOR'ed into @h since the last
33
* AES encryption. This is 0 if no data has been processed yet,
34
* or between 1 and AES_BLOCK_SIZE inclusive otherwise.
35
* @h: The current chaining value
36
*/
37
struct aes_cmac_ctx {
38
const struct aes_cmac_key *key;
39
size_t partial_len;
40
u8 h[AES_BLOCK_SIZE];
41
};
42
43
/**
44
* aes_cmac_preparekey() - Prepare a key for AES-CMAC
45
* @key: (output) The key struct to initialize
46
* @in_key: The raw AES key
47
* @key_len: Length of the raw key in bytes. The supported values are
48
* AES_KEYSIZE_128, AES_KEYSIZE_192, and AES_KEYSIZE_256.
49
*
50
* Context: Any context.
51
* Return: 0 on success or -EINVAL if the given key length is invalid. No other
52
* errors are possible, so callers that always pass a valid key length
53
* don't need to check for errors.
54
*/
55
int aes_cmac_preparekey(struct aes_cmac_key *key, const u8 *in_key,
56
size_t key_len);
57
58
/**
59
* aes_xcbcmac_preparekey() - Prepare a key for AES-XCBC-MAC
60
* @key: (output) The key struct to initialize
61
* @in_key: The raw key. As per the AES-XCBC-MAC specification (RFC 3566), this
62
* is 128 bits, matching the internal use of AES-128.
63
*
64
* AES-XCBC-MAC and AES-CMAC are the same except for the key preparation. After
65
* that step, AES-XCBC-MAC is supported via the aes_cmac_* functions.
66
*
67
* New users should use AES-CMAC instead of AES-XCBC-MAC.
68
*
69
* Context: Any context.
70
*/
71
void aes_xcbcmac_preparekey(struct aes_cmac_key *key,
72
const u8 in_key[at_least AES_KEYSIZE_128]);
73
74
/**
75
* aes_cmac_init() - Start computing an AES-CMAC or AES-XCBC-MAC value
76
* @ctx: (output) The context to initialize
77
* @key: The key to use. Note that a pointer to the key is saved in the
78
* context, so the key must live at least as long as the context.
79
*
80
* This supports both AES-CMAC and AES-XCBC-MAC. Which one is done depends on
81
* whether aes_cmac_preparekey() or aes_xcbcmac_preparekey() was called.
82
*/
83
static inline void aes_cmac_init(struct aes_cmac_ctx *ctx,
84
const struct aes_cmac_key *key)
85
{
86
*ctx = (struct aes_cmac_ctx){ .key = key };
87
}
88
89
/**
90
* aes_cmac_update() - Update an AES-CMAC or AES-XCBC-MAC context with more data
91
* @ctx: The context to update; must have been initialized
92
* @data: The message data
93
* @data_len: The data length in bytes. Doesn't need to be block-aligned.
94
*
95
* This can be called any number of times.
96
*
97
* Context: Any context.
98
*/
99
void aes_cmac_update(struct aes_cmac_ctx *ctx, const u8 *data, size_t data_len);
100
101
/**
102
* aes_cmac_final() - Finish computing an AES-CMAC or AES-XCBC-MAC value
103
* @ctx: The context to finalize; must have been initialized
104
* @out: (output) The resulting MAC
105
*
106
* After finishing, this zeroizes @ctx. So the caller does not need to do it.
107
*
108
* Context: Any context.
109
*/
110
void aes_cmac_final(struct aes_cmac_ctx *ctx, u8 out[at_least AES_BLOCK_SIZE]);
111
112
/**
113
* aes_cmac() - Compute AES-CMAC or AES-XCBC-MAC in one shot
114
* @key: The key to use
115
* @data: The message data
116
* @data_len: The data length in bytes
117
* @out: (output) The resulting AES-CMAC or AES-XCBC-MAC value
118
*
119
* This supports both AES-CMAC and AES-XCBC-MAC. Which one is done depends on
120
* whether aes_cmac_preparekey() or aes_xcbcmac_preparekey() was called.
121
*
122
* Context: Any context.
123
*/
124
static inline void aes_cmac(const struct aes_cmac_key *key, const u8 *data,
125
size_t data_len, u8 out[at_least AES_BLOCK_SIZE])
126
{
127
struct aes_cmac_ctx ctx;
128
129
aes_cmac_init(&ctx, key);
130
aes_cmac_update(&ctx, data, data_len);
131
aes_cmac_final(&ctx, out);
132
}
133
134
/*
135
* AES-CBC-MAC support. This is provided only for use by the implementation of
136
* AES-CCM. It should have no other users. Warning: unlike AES-CMAC and
137
* AES-XCBC-MAC, AES-CBC-MAC isn't a secure MAC for variable-length messages.
138
*/
139
struct aes_cbcmac_ctx {
140
const struct aes_enckey *key;
141
size_t partial_len;
142
u8 h[AES_BLOCK_SIZE];
143
};
144
static inline void aes_cbcmac_init(struct aes_cbcmac_ctx *ctx,
145
const struct aes_enckey *key)
146
{
147
*ctx = (struct aes_cbcmac_ctx){ .key = key };
148
}
149
void aes_cbcmac_update(struct aes_cbcmac_ctx *ctx, const u8 *data,
150
size_t data_len);
151
void aes_cbcmac_final(struct aes_cbcmac_ctx *ctx,
152
u8 out[at_least AES_BLOCK_SIZE]);
153
154
#endif /* _CRYPTO_AES_CBC_MACS_H */
155
156