Implement AES-CMAC.
This commit is contained in:
parent
191a27af86
commit
60e4998d16
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2017,2023 Stephen Heumann
|
||||
Copyright (c) 2017,2023,2024 Stephen Heumann
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
14
Makefile
14
Makefile
|
@ -3,8 +3,8 @@ CFLAGS = -O255 -w255
|
|||
|
||||
LIBRARIES = lib65816crypto lib65816hash
|
||||
|
||||
PROGRAMS = aescbctest aesctrtest aestest aescrypt rc4test sha1sum sha1test \
|
||||
sha256sum sha256test md5sum md5test md4sum md4test hmactest
|
||||
PROGRAMS = aescbctest aesctrtest aestest aescrypt rc4test cmactest sha1sum \
|
||||
sha1test sha256sum sha256test md5sum md5test md4sum md4test hmactest
|
||||
|
||||
.PHONY: default
|
||||
default: $(LIBRARIES) $(PROGRAMS)
|
||||
|
@ -14,6 +14,8 @@ pagealign.root: pagealign.asm
|
|||
mv pagealign.ROOT pagealign.root
|
||||
|
||||
# Encryption/decryption algorithms
|
||||
aescmac.a: aescmac.c aes.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
aesmodes.a: aesmodes.c aes.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
aes.a: aes.asm aes.macros
|
||||
|
@ -42,7 +44,7 @@ md4.a: md4.cc md4.h md4.asm md4.macros hmacimpl.h
|
|||
md4.B: md4.a
|
||||
|
||||
# Libraries
|
||||
lib65816crypto: aesmodes.a aes.a rc4.a rc4.B
|
||||
lib65816crypto: aescmac.a aesmodes.a aes.a rc4.a rc4.B
|
||||
rm -f $@
|
||||
iix makelib -P $@ $(patsubst %,+%,$^)
|
||||
lib65816hash: sha1.a sha1.B sha256.a sha256.B md5.a md5.B md4.a md4.B
|
||||
|
@ -62,6 +64,9 @@ aescrypt.a: aescrypt.c aes.h
|
|||
rc4test.a: rc4test.c rc4.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
cmactest.a: cmactest.c aes.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
sha1sum.a: sha1sum.c sha1.h cksumcommon.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
sha1test.a: sha1test.c sha1.h
|
||||
|
@ -97,6 +102,9 @@ aescrypt: aescrypt.a pagealign.root lib65816crypto
|
|||
rc4test: rc4test.a lib65816crypto
|
||||
$(CC) $(CFLAGS) $< -L. -llib65816crypto -o $@
|
||||
|
||||
cmactest: cmactest.a lib65816crypto
|
||||
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816crypto -o $@
|
||||
|
||||
sha1sum: sha1sum.a lib65816hash
|
||||
$(CC) $(CFLAGS) $< -L. -llib65816hash -o $@
|
||||
sha1test: sha1test.a lib65816hash
|
||||
|
|
23
aes.h
23
aes.h
|
@ -21,6 +21,12 @@ struct aes_context {
|
|||
unsigned char reserved2[16*13];
|
||||
};
|
||||
|
||||
struct aes_cmac_context {
|
||||
struct aes_context ctx;
|
||||
unsigned char k1[16];
|
||||
unsigned char k2[16];
|
||||
};
|
||||
|
||||
/*
|
||||
* The context structure must be in bank 0, preferably page-aligned.
|
||||
* Note that a 256-byte (one page) context structure is sufficient for
|
||||
|
@ -90,3 +96,20 @@ void aes_ctr_process(struct aes_context *context,
|
|||
unsigned char *out,
|
||||
unsigned long nblocks,
|
||||
const unsigned char *counter);
|
||||
|
||||
/*
|
||||
* Initialize a context for AES-CMAC computation with a specified key.
|
||||
* This must be called before any calling aes_cmac_compute.
|
||||
*/
|
||||
void aes_cmac_init(struct aes_cmac_context *context,
|
||||
const unsigned char key[16]);
|
||||
|
||||
/*
|
||||
* Compute the AES-CMAC of a message as a single operation.
|
||||
* The result will be in context->ctx.data.
|
||||
* The context can be reused for multiple aes_cmac_compute operations.
|
||||
*/
|
||||
void aes_cmac_compute(struct aes_cmac_context *context,
|
||||
const unsigned char *message,
|
||||
unsigned long message_length);
|
||||
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Stephen Heumann
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma noroot
|
||||
#pragma lint -1
|
||||
#pragma optimize -1
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "aes.h"
|
||||
|
||||
extern void AES_ENCRYPT(void);
|
||||
|
||||
static asm void aes_cmac_subkey_compute_step(struct aes_cmac_context *ctx) {
|
||||
tdc
|
||||
tay
|
||||
phb
|
||||
plx
|
||||
pla
|
||||
pld
|
||||
sta 1,s
|
||||
phx
|
||||
plb
|
||||
|
||||
sep #0x20
|
||||
asl 15
|
||||
rol 14
|
||||
rol 13
|
||||
rol 12
|
||||
rol 11
|
||||
rol 10
|
||||
rol 9
|
||||
rol 8
|
||||
rol 7
|
||||
rol 6
|
||||
rol 5
|
||||
rol 4
|
||||
rol 3
|
||||
rol 2
|
||||
rol 1
|
||||
rol 0
|
||||
bcc done
|
||||
lda 15
|
||||
eor #0x87
|
||||
sta 15
|
||||
done: rep #0x20
|
||||
|
||||
tya
|
||||
tcd
|
||||
rtl
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize a context for AES-CMAC computation with a specified key.
|
||||
* This must be called before any calling aes_cmac_compute.
|
||||
*/
|
||||
void aes_cmac_init(struct aes_cmac_context *context,
|
||||
const unsigned char key[16])
|
||||
{
|
||||
memcpy(context->ctx.key, key, 16);
|
||||
aes128_expandkey(&context->ctx);
|
||||
|
||||
memset(context->ctx.data, 0, 16);
|
||||
aes_encrypt(&context->ctx);
|
||||
|
||||
aes_cmac_subkey_compute_step(context);
|
||||
memcpy(context->k1, context->ctx.data, 16);
|
||||
|
||||
aes_cmac_subkey_compute_step(context);
|
||||
memcpy(context->k2, context->ctx.data, 16);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compute the AES-CMAC of a message as a single operation.
|
||||
* The result will be in context->ctx.data.
|
||||
* The context can be reused for multiple aes_cmac_compute operations.
|
||||
*/
|
||||
void aes_cmac_compute(struct aes_cmac_context *context,
|
||||
const unsigned char *message,
|
||||
unsigned long message_length)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
memset(&context->ctx.data, 0, 16);
|
||||
|
||||
while (message_length > 16) {
|
||||
asm {
|
||||
lda [message]
|
||||
eor [context]
|
||||
sta [context]
|
||||
ldy #2
|
||||
lda [message],y
|
||||
eor [context],y
|
||||
sta [context],y
|
||||
iny
|
||||
iny
|
||||
lda [message],y
|
||||
eor [context],y
|
||||
sta [context],y
|
||||
iny
|
||||
iny
|
||||
lda [message],y
|
||||
eor [context],y
|
||||
sta [context],y
|
||||
iny
|
||||
iny
|
||||
lda [message],y
|
||||
eor [context],y
|
||||
sta [context],y
|
||||
iny
|
||||
iny
|
||||
lda [message],y
|
||||
eor [context],y
|
||||
sta [context],y
|
||||
iny
|
||||
iny
|
||||
lda [message],y
|
||||
eor [context],y
|
||||
sta [context],y
|
||||
iny
|
||||
iny
|
||||
lda [message],y
|
||||
eor [context],y
|
||||
sta [context],y
|
||||
|
||||
phd
|
||||
lda context
|
||||
tcd
|
||||
jsl AES_ENCRYPT
|
||||
pld
|
||||
}
|
||||
|
||||
message_length -= 16;
|
||||
message += 16;
|
||||
}
|
||||
|
||||
if (message_length == 16) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
context->ctx.data[i] ^= message[i] ^ context->k1[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i < message_length) {
|
||||
context->ctx.data[i] ^= message[i] ^ context->k2[i];
|
||||
} else if (i == message_length) {
|
||||
context->ctx.data[i] ^= 0x80 ^ context->k2[i];
|
||||
} else {
|
||||
context->ctx.data[i] ^= context->k2[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asm {
|
||||
phd
|
||||
lda context
|
||||
tcd
|
||||
jsl AES_ENCRYPT
|
||||
pld
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Stephen Heumann
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aes.h"
|
||||
|
||||
/* AES-CMAC test vectors from RFC 4493 */
|
||||
|
||||
unsigned char K[16] = {
|
||||
0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,
|
||||
0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c
|
||||
};
|
||||
|
||||
unsigned char K1[16] = {
|
||||
0xfb,0xee,0xd6,0x18,0x35,0x71,0x33,0x66,
|
||||
0x7c,0x85,0xe0,0x8f,0x72,0x36,0xa8,0xde
|
||||
};
|
||||
|
||||
unsigned char K2[16] = {
|
||||
0xf7,0xdd,0xac,0x30,0x6a,0xe2,0x66,0xcc,
|
||||
0xf9,0x0b,0xc1,0x1e,0xe4,0x6d,0x51,0x3b
|
||||
};
|
||||
|
||||
unsigned char ex2[16] = {
|
||||
0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
|
||||
0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a
|
||||
};
|
||||
|
||||
unsigned char ex3[40] = {
|
||||
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
|
||||
};
|
||||
|
||||
unsigned char ex4[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
|
||||
};
|
||||
|
||||
|
||||
void print_hexbytes(char *prefix, unsigned char *data, unsigned int n) {
|
||||
int i;
|
||||
|
||||
printf("%s", prefix);
|
||||
for (i = 0; i < n; i++) {
|
||||
printf("%02x ", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct aes_cmac_context *ctx;
|
||||
|
||||
aes_cmac_init(ctx, K);
|
||||
|
||||
if (memcmp(ctx->k1, K1, 16) != 0)
|
||||
print_hexbytes("wrong K1: got ", ctx->k1, 16);
|
||||
if (memcmp(ctx->k2, K2, 16) != 0)
|
||||
print_hexbytes("wrong K2: got ", ctx->k2, 16);
|
||||
|
||||
aes_cmac_compute(ctx, "", 0);
|
||||
print_hexbytes("Example 1 AES-CMAC: ", ctx->ctx.data, 16);
|
||||
aes_cmac_compute(ctx, ex2, sizeof(ex2));
|
||||
print_hexbytes("Example 2 AES-CMAC: ", ctx->ctx.data, 16);
|
||||
aes_cmac_compute(ctx, ex3, sizeof(ex3));
|
||||
print_hexbytes("Example 3 AES-CMAC: ", ctx->ctx.data, 16);
|
||||
aes_cmac_compute(ctx, ex4, sizeof(ex4));
|
||||
print_hexbytes("Example 4 AES-CMAC: ", ctx->ctx.data, 16);
|
||||
}
|
Loading…
Reference in New Issue