RFC 4493
The AES-CMAC Algorithm
RFC 4493: The AES-CMAC Algorithm π¦
Okay bestie, this is the one. RFC 4493 is an Informational document from June 2006, and it was written by JH. Song (Samsung Electronics), R. Poovendran (University of Washington), J. Lee (Samsung Electronics), and T. Iwata (Nagoya University) π . It's not a standard. It just gives the Internet community info about an algorithm that's already cooking. The header doesn't list any obsoletes or updates, so nothing else is being replaced here πΈ.
Status of This Memo β¨
This memo gives information to the Internet community. It doesn't specify an Internet standard of any kind. Distribution of this memo is unlimited.
Copyright Notice π
Copyright (C) The Internet Society (2006).
Abstract π
Okay so NIST recently specified the Cipher-based Message Authentication Code (CMAC), and it's basically the same thing as the One-Key CBC MAC1 (OMAC1) that Iwata and Kurosawa submitted. This memo lays out an authentication algorithm based on CMAC using the 128-bit Advanced Encryption Standard (AES). It's called AES-CMAC, and the whole point is to make it easy for the Internet community to grab and use π§.
Table of Contents π
1. Introduction ....................................................2
2. Specification of AES-CMAC .......................................3
2.1. Basic Definitions ..........................................3
2.2. Overview ...................................................4
2.3. Subkey Generation Algorithm ................................5
2.4. MAC Generation Algorithm ...................................7
2.5. MAC Verification Algorithm .................................9
3. Security Considerations ........................................10
4. Test Vectors ...................................................11
5. Acknowledgement ................................................12
6. References .....................................................12
6.1. Normative References ......................................12
6.2. Informative References ....................................12
Appendix A. Test Code .............................................14
1. Introduction π
NIST recently specified the Cipher-based Message Authentication Code (CMAC). CMAC [NIST-CMAC] is a keyed hash function built on a symmetric key block cipher, like the Advanced Encryption Standard [NIST-AES]. It's equivalent to the One-Key CBC MAC1 (OMAC1) that Iwata and Kurosawa submitted [OMAC1a, OMAC1b]. OMAC1 is an upgrade of the eXtended Cipher Block Chaining mode (XCBC) that Black and Rogaway submitted [XCBCa, XCBCb], and XCBC is itself an upgrade of the basic Cipher Block Chaining-Message Authentication Code (CBC-MAC). The lore is that XCBC fixed the security problems of CBC-MAC, and OMAC1 shrank the key size of XCBC. Iconic glow-up arc π₯.
AES-CMAC gives you way stronger data integrity than a checksum or an error-detecting code. A checksum or error-detecting code only catches accidental changes to the data. CMAC is designed to catch intentional, unauthorized changes too, as well as the accidental ones π.
AES-CMAC is aiming for a similar security goal to HMAC [RFC-HMAC]. The difference is the foundation: AES-CMAC is built on the symmetric key block cipher AES, while HMAC is built on a hash function like SHA-1. So AES-CMAC is a good fit for information systems where AES is easier to get than a hash function π.
This memo specifies the authentication algorithm based on CMAC with AES-128. The new algorithm is named AES-CMAC.
2. Specification of AES-CMAC π¦
2.1. Basic Definitions π
Here's the table of basic definitions you need to understand how AES-CMAC is specified:
x || y Concatenation.
x || y is the string x concatenated with the string
y.
0000 || 1111 is 00001111.
x XOR y Exclusive-OR operation.
For two equal length strings, x and y,
x XOR y is their bit-wise exclusive-OR.
ceil(x) Ceiling function.
The smallest integer no smaller than x.
ceil(3.5) is 4. ceil(5) is 5.
x << 1 Left-shift of the string x by 1 bit.
The most significant bit disappears, and a zero
comes into the least significant bit.
10010001 << 1 is 00100010.
0^n The string that consists of n zero-bits.
0^3 means 000 in binary format.
10^4 means 10000 in binary format.
10^i means 1 followed by i-times repeated
zeros.
MSB(x) The most-significant bit of the string x.
MSB(10010000) means 1.
padding(x) 10^i padded output of input x.
It is described in detail in section 2.4.
Key 128-bit (16-octet) long key for AES-128.
Denoted by K.
First subkey 128-bit (16-octet) long first subkey,
derived through the subkey
generation algorithm from the key K.
Denoted by K1.
Second subkey 128-bit (16-octet) long second subkey,
derived through the subkey
generation algorithm from the key K.
Denoted by K2.
Message A message to be authenticated.
Denoted by M.
The message can be null, which means that the length
of M is 0.
Message length The length of the message M in octets.
Denoted by len.
The minimum value of the length can be 0. The
maximum value of the length is not specified in
this document.
AES-128(K,M) AES-128(K,M) is the 128-bit ciphertext of AES-128
for a 128-bit key, K, and a 128-bit message, M.
MAC A 128-bit string that is the output of AES-CMAC.
Denoted by T.
Validating the MAC provides assurance of the
integrity and authenticity of the message from
the source.
MAC length By default, the length of the output of AES-CMAC is
128 bits. It is possible to truncate the MAC.
The result of the truncation should be taken in most
significant bits first order. The MAC length must be
specified before the communication starts, and
it must not be changed during the lifetime of the
key.
2.2. Overview πΈ
AES-CMAC uses the Advanced Encryption Standard [NIST-AES] as its building block. To generate a MAC, AES-CMAC takes a secret key, a message of variable length, and the length of that message in octets as inputs, and it returns a fixed-bit string called a MAC β¨.
The core of AES-CMAC is the basic CBC-MAC. For a message M that needs to be authenticated, the CBC-MAC gets applied to M. CMAC has two cases of operation, and Figure 2.1 shows what the CBC-MAC does in each one. If the input message is a positive multiple of the block size (that's 128 bits), the last block shall be exclusive-OR'ed with K1 before processing. Otherwise, the last block shall be padded with 10^i (the notation is explained in section 2.1) and exclusive-OR'ed with K2. The result of that step becomes the input to the last encryption. The output of AES-CMAC gives data integrity for the whole input message, which is the whole point π«Ά.
+-----+ +-----+ +-----+ +-----+ +-----+ +---+----+
| M_1 | | M_2 | | M_n | | M_1 | | M_2 | |M_n|10^i|
+-----+ +-----+ +-----+ +-----+ +-----+ +---+----+
| | | +--+ | | | +--+
| +--->(+) +--->(+)<-|K1| | +--->(+) +--->(+)<-|K2|
| | | | | +--+ | | | | | +--+
+-----+ | +-----+ | +-----+ +-----+ | +-----+ | +-----+
|AES_K| | |AES_K| | |AES_K| |AES_K| | |AES_K| | |AES_K|
+-----+ | +-----+ | +-----+ +-----+ | +-----+ | +-----+
| | | | | | | | | |
+-----+ +-----+ | +-----+ +-----+ |
| |
+-----+ +-----+
| T | | T |
+-----+ +-----+
(a) positive multiple block length (b) otherwise
Figure 2.1. Illustration of the two cases of AES-CMAC
AES_K is AES-128 with key K. The message M gets split into blocks M_1,...,M_n, where M_i is the i-th message block. Each M_i is 128 bits for i = 1,...,n-1, and the last block, M_n, is less than or equal to 128 bits. K1 is the subkey for case (a), and K2 is the subkey for case (b). Both K1 and K2 come from the subkey generation algorithm in section 2.3 π.
2.3. Subkey Generation Algorithm β¨
okay so the subkey generation algorithm, Generate_Subkey(), takes a secret key K, which is literally just the AES-128 key π. It spits out two subkeys, K1 and K2, and we write that as (K1,K2) := Generate_Subkey(K) π
Both subkeys get used in MAC generation AND MAC verification π«Ά K1 is for when the last block is exactly the block length, and K2 is for when the last block is shorter than the block length.
Here's the algorithm, Figure 2.2:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Algorithm Generate_Subkey +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Input : K (128-bit key) +
+ Output : K1 (128-bit first subkey) +
+ K2 (128-bit second subkey) +
+-------------------------------------------------------------------+
+ +
+ Constants: const_Zero is 0x00000000000000000000000000000000 +
+ const_Rb is 0x00000000000000000000000000000087 +
+ Variables: L for output of AES-128 applied to 0^128 +
+ +
+ Step 1. L := AES-128(K, const_Zero); +
+ Step 2. if MSB(L) is equal to 0 +
+ then K1 := L << 1; +
+ else K1 := (L << 1) XOR const_Rb; +
+ Step 3. if MSB(K1) is equal to 0 +
+ then K2 := K1 << 1; +
+ else K2 := (K1 << 1) XOR const_Rb; +
+ Step 4. return K1, K2; +
+ +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Figure 2.2. Algorithm Generate_Subkey
Breaking it down, bestie π§
- Step 1: AES-128 with key
Kgets run on an all-zero input block πΈ - Step 2:
K1depends on the MSB ofL. If that MSB is 0,K1is justLleft-shifted by 1 bit. Otherwise,K1is the XOR ofconst_RbandLleft-shifted by 1 bit π - Step 3:
K2follows the same vibe but withK1. If the MSB ofK1is 0,K2isK1left-shifted by 1 bit. Otherwise,K2is the XOR ofconst_RbandK1left-shifted by 1 bit π¦ - Step 4: return
(K1,K2) := Generate_Subkey(K)π
The math behind steps 2 and 3, including const_Rb, is explained in [OMAC1a]. β¨
2.4. MAC Generation Algorithm π
the MAC generation algorithm, AES-CMAC(), takes three inputs: a secret key, a message, and the message length in octets. The secret key is K, which is again just the AES-128 key π The message is M and its length in octets is len. The message M is written as a sequence of blocks M_i, where M_i is the i-th message block. So if M has n blocks, it looks like this:
M = M_1 || M_2 || ... || M_{n-1} || M_n
Every block M_i is 128 bits for i = 1,...,n-1, and the last block M_n is less than or equal to 128 bits π
The output is a 128-bit string called a MAC, which is used to validate the input message. We write the MAC as T, so T := AES-CMAC(K,M,len). Validating the MAC gives you assurance of the integrity and authenticity of the message from the source π«Ά
You can truncate the MAC, and this is the lowkey important part π According to [NIST-CMAC], at least a 64-bit MAC should be used as protection against guessing attacks. The truncation should be taken in most significant bits first order π₯
The AES-128 block length is 128 bits (16 octets). If the message length is not a positive multiple of the block length, there's a special treatment: M gets padded with the bit-string 10^i so the last block is extended up to the block length π
For an input string x of r octets, where 0 <= r < 16, the padding function padding(x) works like this:
padding(x) = x || 10^iwhereiis128-8*r-1
So padding(x) is x, plus a single '1', plus the minimum number of '0's needed to make the total length exactly 128 bits. Iconic β¨
Figure 2.3 describes the MAC generation algorithm:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Algorithm AES-CMAC +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Input : K ( 128-bit key ) +
+ : M ( message to be authenticated ) +
+ : len ( length of the message in octets ) +
+ Output : T ( message authentication code ) +
+ +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Constants: const_Zero is 0x00000000000000000000000000000000 +
+ const_Bsize is 16 +
+ +
+ Variables: K1, K2 for 128-bit subkeys +
+ M_i is the i-th block (i=1..ceil(len/const_Bsize)) +
+ M_last is the last block xor-ed with K1 or K2 +
+ n for number of blocks to be processed +
+ r for number of octets of last block +
+ flag for denoting if last block is complete or not +
+ +
+ Step 1. (K1,K2) := Generate_Subkey(K); +
+ Step 2. n := ceil(len/const_Bsize); +
+ Step 3. if n = 0 +
+ then +
+ n := 1; +
+ flag := false; +
+ else +
+ if len mod const_Bsize is 0 +
+ then flag := true; +
+ else flag := false; +
+ +
+ Step 4. if flag is true +
+ then M_last := M_n XOR K1; +
+ else M_last := padding(M_n) XOR K2; +
+ Step 5. X := const_Zero; +
+ Step 6. for i := 1 to n-1 do +
+ begin +
+ Y := X XOR M_i; +
+ X := AES-128(K,Y); +
+ end +
+ Y := M_last XOR X; +
+ T := AES-128(K,Y); +
+ Step 7. return T; +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Figure 2.3. Algorithm AES-CMAC
Now the step-by-step tea β
- Step 1:
K1andK2get derived fromKthrough the subkey generation algorithm π - Step 2: we calculate the number of blocks,
n. It's the smallest integer greater than or equal tolendivided by the block length of 16 octets π - Step 3: we check the input length. If it's 0 (null), the number of blocks to be processed shall be 1, and the flag shall be marked as not-complete-block (false). Otherwise, if the last block length is 128 bits, the flag is marked as complete-block (true). If not, the flag is marked as not-complete-block (false) π«
- Step 4:
M_lastisM_nXORed with one of the subkeys. If the last block is complete (true),M_lastisM_nXORK1. Otherwise,M_lastispadding(M_n)XORK2π¦ - Step 5: we initialize
XπΈ - Step 6: the basic CBC-MAC runs over
M_1,...,M_{n-1},M_lastπ₯ - Step 7: the 128-bit MAC,
T := AES-CMAC(K,M,len), gets returned π
And if necessary, the MAC gets truncated before it's returned. β¨
2.5. MAC Verification Algorithm β¨
okay bestie, so verifying a MAC is literally just... doing the MAC generation again and seeing if it matches π we reuse the generation algorithm from section 2.4 (no notes, it's the same vibe) π¦
the verify function, Verify_MAC(), takes four inputs: a secret key, a message, the length of the message in octets, and the received MAC. these are called K, M, len, and T' respectively π
the output is either INVALID or VALID. that's it, that's the whole menu π
Figure 2.4 is the algorithm, and it's giving very clean energy πΈ
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Algorithm Verify_MAC +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Input : K ( 128-bit Key ) +
+ : M ( message to be verified ) +
+ : len ( length of the message in octets ) +
+ : T' ( the received MAC to be verified ) +
+ Output : INVALID or VALID +
+ +
+-------------------------------------------------------------------+
+ +
+ Step 1. T* := AES-CMAC(K,M,len); +
+ Step 2. if T* is equal to T' +
+ then +
+ return VALID; +
+ else +
+ return INVALID; +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Figure 2.4. Algorithm Verify_MAC
so step 1 is: make T* from K, M, and len using the generation algorithm π§
step 2 is the glow-up moment: compare T* with T'. if they match, return VALID π«Ά if they don't, return INVALID π
if the output is INVALID, the message is definitely not authentic π« like, it did not come from a source that ran the generation process on that message to make the purported MAC. no vibes, just facts π
if the output is VALID, the design of AES-CMAC gives you assurance that the message is authentic and therefore wasn't corrupted in transit π BUT, and this is important bestie, that assurance is not absolute. same as for ANY MAC algorithm π
3. Security Considerations π₯
okay this section is SERIOUS, so pay attention bestie π
AES-CMAC is built on the strong cryptographic algorithm AES πͺ however (and this is true for every crypto algorithm ever), a big part of its strength lives in the secret key K, plus the implementation being correct in every participating system π
if the secret key gets compromised or shared inappropriately, AES-CMAC guarantees neither authentication nor integrity of the message. at all. zero. nada. π
the secret key SHALL be generated in a way that meets the pseudo randomness requirement of RFC 4086 [RFC4086], and it SHOULD be kept safe π¦
if and only if AES-CMAC is used properly does it provide the authentication and integrity that meet the best current practice of message authentication ππΈ
4. Test Vectors π§ͺ
these test vectors are the same as the ones in [NIST-CMAC] π and they're also the output of the test program in Appendix A β¨
--------------------------------------------------
Subkey Generation
K 2b7e1516 28aed2a6 abf71588 09cf4f3c
AES-128(key,0) 7df76b0c 1ab899b3 3e42f047 b91b546f
K1 fbeed618 35713366 7c85e08f 7236a8de
K2 f7ddac30 6ae266cc f90bc11e e46d513b
--------------------------------------------------
--------------------------------------------------
Example 1: len = 0
M <empty string>
AES-CMAC bb1d6929 e9593728 7fa37d12 9b756746
--------------------------------------------------
Example 2: len = 16
M 6bc1bee2 2e409f96 e93d7e11 7393172a
AES-CMAC 070a16b4 6b4d4144 f79bdd9d d04a287c
--------------------------------------------------
Example 3: len = 40
M 6bc1bee2 2e409f96 e93d7e11 7393172a
ae2d8a57 1e03ac9c 9eb76fac 45af8e51
30c81c46 a35ce411
AES-CMAC dfa66747 de9ae630 30ca3261 1497c827
--------------------------------------------------
Example 4: len = 64
M 6bc1bee2 2e409f96 e93d7e11 7393172a
ae2d8a57 1e03ac9c 9eb76fac 45af8e51
30c81c46 a35ce411 e5fbc119 1a0a52ef
f69f2445 df4f9b17 ad2b417b e66c3710
AES-CMAC 51f0bebf 7e3b9d92 fc497417 79363cfe
--------------------------------------------------
5. Acknowledgement π«Ά
portions of the text here are borrowed from [NIST-CMAC] π big thanks to the OMAC1 authors, the SP 800-38B author, and Russ Housley for his useful comments and guidance, which got folded in π we also thank Alfred Hoenes for lots of useful comments π· this memo was prepared while Tetsu Iwata was at Ibaraki University, Japan πΎ
we acknowledge support from these grants: Collaborative Technology Alliance (CTA) from US Army Research Laboratory, DAAD19-01-2-0011; Presidential Award from Army Research Office, W911NF-05-1-0491; NSF CAREER ANI-0093187 π results do not reflect any position of the funding agencies π
6. References π
6.1. Normative References π
[NIST-CMAC] NIST, Special Publication 800-38B, "Recommendation for
Block Cipher Modes of Operation: The CMAC Mode for
Authentication", May 2005.
[NIST-AES] NIST, FIPS 197, "Advanced Encryption Standard (AES)",
November 2001.
http://csrc.nist.gov/publications/fips/fips197/fips-
197.pdf
[RFC4086] Eastlake, D., 3rd, Schiller, J., and S. Crocker,
"Randomness Requirements for Security", BCP 106, RFC
4086, June 2005.
6.2. Informative References π
[RFC-HMAC] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC:
Keyed-Hashing for Message Authentication", RFC 2104,
February 1997.
[OMAC1a] Tetsu Iwata and Kaoru Kurosawa, "OMAC: One-Key CBC MAC",
Fast Software Encryption, FSE 2003, LNCS 2887, pp. 129-
153, Springer-Verlag, 2003.
[OMAC1b] Tetsu Iwata and Kaoru Kurosawa, "OMAC: One-Key CBC MAC",
Submission to NIST, December 2002. Available from the
NIST modes of operation web site at
http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/
omac/omac-spec.pdf
[XCBCa] John Black and Phillip Rogaway, "A Suggestion for
Handling Arbitrary-Length Messages with the CBC MAC",
NIST Second Modes of Operation Workshop, August 2001.
Available from the NIST modes of operation web site at
http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/
xcbc-mac/xcbc-mac-spec.pdf
[XCBCb] John Black and Phillip Rogaway, "CBC MACs for Arbitrary-
Length Messages: The Three-Key Constructions", Journal of
Cryptology, Vol. 18, No. 2, pp. 111-132, Springer-Verlag,
Spring 2005.
Appendix A. Test Code β¨
okay so this is the C source that spits out the test vectors from earlier in the memo π§ͺ it's there to check that the algorithm is correct, and it's NOT meant for commercial products π ββοΈ so keep it in your lab bestie π
/****************************************************************/
/* AES-CMAC with AES-128 bit */
/* CMAC Algorithm described in SP800-38B */
/* Author: Junhyuk Song (junhyuk.song@samsung.com) */
/* Jicheol Lee (jicheol.lee@samsung.com) */
/****************************************************************/
#include <stdio.h>
/* For CMAC Calculation */
unsigned char const_Rb[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
};
unsigned char const_Zero[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* Basic Functions */
void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
{
int i;
for (i=0;i<16; i++)
{
out[i] = a[i] ^ b[i];
}
}
void print_hex(char *str, unsigned char *buf, int len)
{
int i;
for ( i=0; i<len; i++ ) {
if ( (i % 16) == 0 && i != 0 ) printf(str);
printf("%02x", buf[i]);
if ( (i % 4) == 3 ) printf(" ");
if ( (i % 16) == 15 ) printf("\n");
}
if ( (i % 16) != 0 ) printf("\n");
}
void print128(unsigned char *bytes)
{
int j;
for (j=0; j<16;j++) {
printf("%02x",bytes[j]);
if ( (j%4) == 3 ) printf(" ");
}
}
void print96(unsigned char *bytes)
{
int j;
for (j=0; j<12;j++) {
printf("%02x",bytes[j]);
if ( (j%4) == 3 ) printf(" ");
}
}
/* AES-CMAC Generation Function */
void leftshift_onebit(unsigned char *input,unsigned char *output)
{
int i;
unsigned char overflow = 0;
for ( i=15; i>=0; i-- ) {
output[i] = input[i] << 1;
output[i] |= overflow;
overflow = (input[i] & 0x80)?1:0;
}
return;
}
void generate_subkey(unsigned char *key, unsigned char *K1, unsigned
char *K2)
{
unsigned char L[16];
unsigned char Z[16];
unsigned char tmp[16];
int i;
for ( i=0; i<16; i++ ) Z[i] = 0;
AES_128(key,Z,L);
if ( (L[0] & 0x80) == 0 ) { /* If MSB(L) = 0, then K1 = L << 1 */
leftshift_onebit(L,K1);
} else { /* Else K1 = ( L << 1 ) (+) Rb */
leftshift_onebit(L,tmp);
xor_128(tmp,const_Rb,K1);
}
if ( (K1[0] & 0x80) == 0 ) {
leftshift_onebit(K1,K2);
} else {
leftshift_onebit(K1,tmp);
xor_128(tmp,const_Rb,K2);
}
return;
}
void padding ( unsigned char *lastb, unsigned char *pad, int length )
{
int j;
/* original last block */
for ( j=0; j<16; j++ ) {
if ( j < length ) {
pad[j] = lastb[j];
} else if ( j == length ) {
pad[j] = 0x80;
} else {
pad[j] = 0x00;
}
}
}
void AES_CMAC ( unsigned char *key, unsigned char *input, int length,
unsigned char *mac )
{
unsigned char X[16],Y[16], M_last[16], padded[16];
unsigned char K1[16], K2[16];
int n, i, flag;
generate_subkey(key,K1,K2);
n = (length+15) / 16; /* n is number of rounds */
if ( n == 0 ) {
n = 1;
flag = 0;
} else {
if ( (length%16) == 0 ) { /* last block is a complete block */
flag = 1;
} else { /* last block is not complete block */
flag = 0;
}
}
if ( flag ) { /* last block is complete block */
xor_128(&input[16*(n-1)],K1,M_last);
} else {
padding(&input[16*(n-1)],padded,length%16);
xor_128(padded,K2,M_last);
}
for ( i=0; i<16; i++ ) X[i] = 0;
for ( i=0; i<n-1; i++ ) {
xor_128(X,&input[16*i],Y); /* Y := Mi (+) X */
AES_128(key,Y,X); /* X := AES-128(KEY, Y); */
}
xor_128(X,M_last,Y);
AES_128(key,Y,X);
for ( i=0; i<16; i++ ) {
mac[i] = X[i];
}
}
int main()
{
unsigned char L[16], K1[16], K2[16], T[16], TT[12];
unsigned char M[64] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
};
unsigned char key[16] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
};
printf("--------------------------------------------------\n");
printf("K "); print128(key); printf("\n");
printf("\nSubkey Generation\n");
AES_128(key,const_Zero,L);
printf("AES_128(key,0) "); print128(L); printf("\n");
generate_subkey(key,K1,K2);
printf("K1 "); print128(K1); printf("\n");
printf("K2 "); print128(K2); printf("\n");
printf("\nExample 1: len = 0\n");
printf("M "); printf("<empty string>\n");
AES_CMAC(key,M,0,T);
printf("AES_CMAC "); print128(T); printf("\n");
printf("\nExample 2: len = 16\n");
printf("M "); print_hex(" ",M,16);
AES_CMAC(key,M,16,T);
printf("AES_CMAC "); print128(T); printf("\n");
printf("\nExample 3: len = 40\n");
printf("M "); print_hex(" ",M,40);
AES_CMAC(key,M,40,T);
printf("AES_CMAC "); print128(T); printf("\n");
printf("\nExample 4: len = 64\n");
printf("M "); print_hex(" ",M,64);
AES_CMAC(key,M,64,T);
printf("AES_CMAC "); print128(T); printf("\n");
printf("--------------------------------------------------\n");
return 0;
}
Authors' Addresses π
Junhyuk Song πΈ University of Washington Samsung Electronics Phone: (206) 853-5843 EMail: songlee@ee.washington.edu, junhyuk.song@samsung.com
Jicheol Lee πΈ Samsung Electronics Phone: +82-31-279-3605 EMail: jicheol.lee@samsung.com
Radha Poovendran πΈ Network Security Lab University of Washington Phone: (206) 221-6512 EMail: radha@ee.washington.edu
Tetsu Iwata πΈ Nagoya University EMail: iwata@cse.nagoya-u.ac.jp
Full Copyright Statement π
Copyright (C) The Internet Society (2006).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property π₯
The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.
Acknowledgement π«Ά
Funding for the RFC Editor function is provided by the IETF Administrative Support Activity (IASA). π
π¦ where this page comes from
- ietf: rfc4493 2006-06
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms