diff --git a/aes.asm b/aes.asm index cd62c0e..1c49026 100644 --- a/aes.asm +++ b/aes.asm @@ -377,6 +377,10 @@ finish_aes128 anop * The encrypted input and unencrypted output are in state1. * Callable from C, with context structure pointer on stack. +aes_decrypt start + CFunction AES_DECRYPT + end + aes128_decrypt start CFunction AES128_DECRYPT end @@ -391,9 +395,18 @@ aes256_decrypt start * Call with DP = AES context structure (with key expanded), * DP = bank containing AES tables. -AES256_DECRYPT start +AES_DECRYPT start using tables ShortRegs + lda keysize + bne not128 + jmp aes128_decrypt_internal +not128 bmi aes256_decrypt_internal + jmp aes192_decrypt_internal + +AES256_DECRYPT entry + ShortRegs +aes256_decrypt_internal anop InvFinalRound 14 InvNormalRound 13 InvNormalRound 12 @@ -401,6 +414,7 @@ AES256_DECRYPT start AES192_DECRYPT entry ShortRegs +aes192_decrypt_internal anop InvFinalRound 12 cont1 anop InvNormalRound 11 @@ -409,6 +423,7 @@ cont1 anop AES128_DECRYPT entry ShortRegs +aes128_decrypt_internal anop InvFinalRound 10 cont2 anop InvNormalRound 9 diff --git a/aes.h b/aes.h index cb57b3e..be16826 100644 --- a/aes.h +++ b/aes.h @@ -45,8 +45,33 @@ void aes_encrypt(struct aes_context *context); /* * AES decryption functions + * aes_decrypt does AES-128, AES-192, or AES-256 decryption, based on the key. + * The others use a specific key size; a corresponding key must have been used. * The encrypted input and unencrypted output are in context->data. */ +void aes_decrypt(struct aes_context *context); void aes128_decrypt(struct aes_context *context); void aes192_decrypt(struct aes_context *context); void aes256_decrypt(struct aes_context *context); + +/* + * Encrypt data using AES-128, AES-192, or AES-256 in CBC mode. + * The key must have been specified via aes{128,192,256}_expandkey(). + * The initialization vector (IV) must be in context->data. + * nblocks gives the number of 16-byte blocks to be processed. + */ +void aes_cbc_encrypt(struct aes_context *context, + const unsigned char *in, + unsigned char *out, + unsigned long nblocks); + +/* + * Decrypt data using AES-128, AES-192, or AES-256 in CBC mode. + * The key must have been specified via aes{128,192,256}_expandkey(). + * nblocks gives the number of 16-byte blocks to be processed. + */ +void aes_cbc_decrypt(struct aes_context *context, + const unsigned char *in, + unsigned char *out, + unsigned long nblocks, + const unsigned char *iv); diff --git a/aescbc.c b/aescbc.c new file mode 100644 index 0000000..895d2a5 --- /dev/null +++ b/aescbc.c @@ -0,0 +1,196 @@ +#pragma noroot +#pragma lint -1 +#pragma optimize -1 + +#include +#include "aes.h" + +extern void AES_ENCRYPT(void); +extern void AES_DECRYPT(void); + +/* + * Encrypt data using AES-128, AES-192, or AES-256 in CBC mode. + * The key must have been specified via aes{128,192,256}_expandkey(). + * The initialization vector (IV) must be in context->data. + * nblocks gives the number of 16-byte blocks to be processed. + */ +void aes_cbc_encrypt(struct aes_context *context, + const unsigned char *in, + unsigned char *out, + unsigned long nblocks) +{ + + + while (nblocks-- > 0) { + asm { + ldy #0 + lda [in],y + eor [context],y + sta [context],y + iny + iny + lda [in],y + eor [context],y + sta [context],y + iny + iny + lda [in],y + eor [context],y + sta [context],y + iny + iny + lda [in],y + eor [context],y + sta [context],y + iny + iny + lda [in],y + eor [context],y + sta [context],y + iny + iny + lda [in],y + eor [context],y + sta [context],y + iny + iny + lda [in],y + eor [context],y + sta [context],y + iny + iny + lda [in],y + eor [context],y + sta [context],y + + phd + lda context + tcd + jsl AES_ENCRYPT + pld + } + memcpy(out, context->data, 16); + in += 16; + out += 16; + } +} + + +/* + * Decrypt data using AES-128, AES-192, or AES-256 in CBC mode. + * The key must have been specified via aes{128,192,256}_expandkey(). + * nblocks gives the number of 16-byte blocks to be processed. + */ +void aes_cbc_decrypt(struct aes_context *context, + const unsigned char *in, + unsigned char *out, + unsigned long nblocks, + const unsigned char *iv) +{ + if (nblocks-- == 0) + return; + + memcpy(context->data, in, 16); + asm { + phd + lda context + tcd + jsl AES_DECRYPT + pld + + ldy #0 + lda [context],y + eor [iv],y + sta [out],y + iny + iny + lda [context],y + eor [iv],y + sta [out],y + iny + iny + lda [context],y + eor [iv],y + sta [out],y + iny + iny + lda [context],y + eor [iv],y + sta [out],y + iny + iny + lda [context],y + eor [iv],y + sta [out],y + iny + iny + lda [context],y + eor [iv],y + sta [out],y + iny + iny + lda [context],y + eor [iv],y + sta [out],y + iny + iny + lda [context],y + eor [iv],y + sta [out],y + } + //in += 16; + out += 16; + + while (nblocks-- > 0) { + memcpy(context->data, in+16, 16); + asm { + phd + lda context + tcd + jsl AES_DECRYPT + pld + + ldy #0 + lda [context],y + eor [in],y + sta [out],y + iny + iny + lda [context],y + eor [in],y + sta [out],y + iny + iny + lda [context],y + eor [in],y + sta [out],y + iny + iny + lda [context],y + eor [in],y + sta [out],y + iny + iny + lda [context],y + eor [in],y + sta [out],y + iny + iny + lda [context],y + eor [in],y + sta [out],y + iny + iny + lda [context],y + eor [in],y + sta [out],y + iny + iny + lda [context],y + eor [in],y + sta [out],y + } + in += 16; + out += 16; + } +} diff --git a/aescbctest.c b/aescbctest.c new file mode 100644 index 0000000..e97dd68 --- /dev/null +++ b/aescbctest.c @@ -0,0 +1,89 @@ +#include +#include +#include "aes.h" + +unsigned char iv[16] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f +}; + +unsigned char key128[16] = { + 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, + 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c +}; + +unsigned char key192[24] = { + 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52, + 0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5, + 0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b +}; + +unsigned char key256[32] = { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 +}; + +unsigned char plaintext[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 output[64]; +unsigned char output2[64]; + +static void printhex(char *str, unsigned char *buf, unsigned int count) { + unsigned int i; + + if (str) + printf("%s\n", str); + + for (i = 0; i < count; i++) { + printf("%02x", buf[i]); + if (i && (i & 0x0F) == 0x0F) + printf("\n"); + } +} + +int main(void) { + struct aes_context context; + + memcpy(context.key, key128, 16); + aes128_expandkey(&context); + + memcpy(context.data, iv, 16); + aes_cbc_encrypt(&context, plaintext, output, 4); + printhex("AES-128 ciphertext:", output, 64); + + aes_cbc_decrypt(&context, output, output2, 4, iv); + printhex("Decrypted plaintext:", output2, 64); + + + memcpy(context.key, key192, 24); + aes192_expandkey(&context); + + memcpy(context.data, iv, 16); + aes_cbc_encrypt(&context, plaintext, output, 4); + printhex("AES-192 ciphertext:", output, 64); + + aes_cbc_decrypt(&context, output, output2, 4, iv); + printhex("Decrypted plaintext:", output2, 64); + + + memcpy(context.key, key256, 32); + aes256_expandkey(&context); + + memcpy(context.data, iv, 16); + aes_cbc_encrypt(&context, plaintext, output, 4); + printhex("AES-256 ciphertext:", output, 64); + + aes_cbc_decrypt(&context, output, output2, 4, iv); + printhex("Decrypted plaintext:", output2, 64); +}