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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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
//! AES-CMAC (Cipher-based Message Authentication Code) Implementation
//!
//! This module provides functionality for computing the AES-CMAC, a message authentication code
//! based on AES and the CMAC algorithm, as specified in RFC 4493. AES-CMAC is designed to provide
//! stronger assurance of data integrity than traditional checksums or error-detecting codes,
//! effectively detecting both accidental and intentional unauthorized data modifications.
//!
//! AES-CMAC is based on the Advanced Encryption Standard (AES) and is equivalent to the One-Key
//! CBC MAC1 (OMAC1), an improvement over eXtended Cipher Block Chaining mode (XCBC) and the basic
//! Cipher Block Chaining-Message Authentication Code (CBC-MAC). This algorithm achieves a security
//! goal similar to HMAC but uses AES, making it more appropriate in systems where AES is more
//! readily available than hash functions.
//!
//! The implementation focuses on AES-CMAC with a 128-bit key (AES-128), a 192-bit key (AES-192)
//! or a 256-bit key (AES-256), providing a secure method to authenticate messages. It is
//! particularly useful in scenarios where data integrity and authenticity are of high importance
//! and where AES is a preferred choice over hash-based MACs like HMAC.
//!
//! # Features
//!
//! - `aes_cmac`: Computes the AES-CMAC for a given message and an AES key.
//!
//! - `generate_subkey`: Generates subkeys used in the CMAC algorithm from a given AES key.
//!
//! # Usage
//!
//! AES-CMAC is suitable for various cryptographic applications, especially in systems where AES is
//! preferred or more efficient than hash functions. It provides strong authentication and is
//! simpler to implement in environments where AES is already available.
//!
//! # Example
//!
//! Compute the AES-CMAC for a specific message and key as per RFC 4493 test vector:
//!
//! ```
//! use crate::soft_aes::aes::aes_cmac;
//! use hex::decode as hex_decode;
//!
//! // Key and message are given in hexadecimal format
//! let key = hex_decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap();
//! let message = hex_decode("6bc1bee22e409f96e93d7e117393172a").unwrap();
//!
//! let mac = aes_cmac(&message, &key).unwrap();
//!
//! // The resulting MAC should match the specified test vector
//! assert_eq!(
//! mac.to_vec(),
//! hex_decode("070a16b46b4d4144f79bdd9dd04a287c").unwrap()
//! );
//! ```
//!
//! This example uses the `hex_decode` function from the `hex` crate to convert the hexadecimal strings
//! into byte arrays for the key and message. The resulting MAC is then compared against the expected value
//! from the test vector.
//!
//! # References
//!
//! - RFC 4493: The AES-CMAC Algorithm
//! [https://www.rfc-editor.org/rfc/rfc4493]
//! - NIST SP 800-38B: Recommendation for Block Cipher Modes of Operation:
//! [https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf]
//! - Related cryptographic standards: OMAC1, XCBC, CBC-MAC
//!
//! # Disclaimer
//!
//! - While AES-CMAC provides strong data integrity assurance, it is important to use it
//! correctly. Ensure that keys are securely managed and never reused across different
//! security contexts.
//!
//! - This implementation aims for clarity and adherence to the standard. For high-performance
//! requirements, further optimizations may be necessary.
use *;
use cratepad_80;
use Error;
const CONST_ZERO: = ;
const CONST_RB: = ;
/// Generate subkeys for AES-CMAC.
///
/// # Parameters
/// - `key`: AES-128, AES-192 or AES-256 key.
///
/// # Returns
/// Returns a tuple of two 128-bit subkeys `(K1, K2)` or an error if
/// the encryption fails.
/// Compute AES-CMAC for a given message using a specified key.
///
/// AES-CMAC is a message authentication code based on AES and CMAC (Cipher-based MAC).
/// This function calculates the MAC (Message Authentication Code) using the AES-128
/// algorithm in CMAC mode as per the specification in RFC 4493.
///
/// # Arguments
///
/// * `message` - The message for which to compute the MAC.
/// * `key` - AES-128, AES-192 or AES-256 key.
///
/// # Returns
///
/// A `Result` containing the computed MAC as a 128-bit array if successful, or an error.
///
/// # Errors
///
/// Returns an error if any cryptographic operation fails.
/// Helper function to XOR a block with a subkey.
/// XOR two 128-bit blocks.
/// Perform a left bitwise shift by one bit on a 16-byte array.