aboutsummaryrefslogtreecommitdiff
path: root/aes.c
diff options
context:
space:
mode:
authortoni <matzeton@googlemail.com>2017-01-11 01:29:06 +0100
committertoni <matzeton@googlemail.com>2017-01-11 01:29:06 +0100
commitca95d761f5d97e677931145e29dd09ab09d01b43 (patch)
treecb492d16fc7435e6b1f0451e059e07af642de976 /aes.c
parentb7e4f6cb468a3d9f1bca1953cd44a52fcf392c1d (diff)
moved sources to https://github.com/lnslbrty/foo-scripts
Diffstat (limited to 'aes.c')
-rw-r--r--aes.c411
1 files changed, 0 insertions, 411 deletions
diff --git a/aes.c b/aes.c
deleted file mode 100644
index ba31b41..0000000
--- a/aes.c
+++ /dev/null
@@ -1,411 +0,0 @@
-// AES Implementation by X-N2O
-// Started: 15:41:35 - 18 Nov 2009
-// Finished: 20:03:59 - 21 Nov 2009
-// Logarithm, S-Box, and RCON tables are not hardcoded
-// Instead they are generated when the program starts
-// All of the code below is based from the AES specification
-// You can find it at http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
-// You may use this code as you wish, but do not remove this comment
-// This is only a proof of concept, and should not be considered as the most efficient implementation
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#define AES_RPOL 0x011b // reduction polynomial (x^8 + x^4 + x^3 + x + 1)
-#define AES_GEN 0x03 // gf(2^8) generator (x + 1)
-#define AES_SBOX_CC 0x63 // S-Box C constant
-
-#define KEY_128 (128/8)
-#define KEY_192 (192/8)
-#define KEY_256 (256/8)
-
-#define aes_mul(a, b) ((a)&&(b)?g_aes_ilogt[(g_aes_logt[(a)]+g_aes_logt[(b)])%0xff]:0)
-#define aes_inv(a) ((a)?g_aes_ilogt[0xff-g_aes_logt[(a)]]:0)
-
-unsigned char g_aes_logt[256], g_aes_ilogt[256];
-unsigned char g_aes_sbox[256], g_aes_isbox[256];
-
-typedef struct {
- unsigned char state[4][4];
- int kcol;
- size_t rounds;
- unsigned long keysched[0];
-} aes_ctx_t;
-
-void aes_init();
-aes_ctx_t *aes_alloc_ctx(unsigned char *key, size_t keyLen);
-inline unsigned long aes_subword(unsigned long w);
-inline unsigned long aes_rotword(unsigned long w);
-void aes_keyexpansion(aes_ctx_t *ctx);
-
-inline unsigned char aes_mul_manual(unsigned char a, unsigned char b); // use aes_mul instead
-
-void aes_subbytes(aes_ctx_t *ctx);
-void aes_shiftrows(aes_ctx_t *ctx);
-void aes_mixcolumns(aes_ctx_t *ctx);
-void aes_addroundkey(aes_ctx_t *ctx, int round);
-void aes_encrypt(aes_ctx_t *ctx, unsigned char input[16], unsigned char output[16]);
-
-void aes_invsubbytes(aes_ctx_t *ctx);
-void aes_invshiftrows(aes_ctx_t *ctx);
-void aes_invmixcolumns(aes_ctx_t *ctx);
-void aes_decrypt(aes_ctx_t *ctx, unsigned char input[16], unsigned char output[16]);
-
-void aes_free_ctx(aes_ctx_t *ctx);
-
-void init_aes()
-{
- int i;
- unsigned char gen;
-
- // build logarithm table and it's inverse
- gen = 1;
- for(i = 0; i < 0xff; i++) {
- g_aes_logt[gen] = i;
- g_aes_ilogt[i] = gen;
- gen = aes_mul_manual(gen, AES_GEN);
- }
-
- // build S-Box and it's inverse
- for(i = 0; i <= 0xff; i++) {
- char bi;
- unsigned char inv = aes_inv(i);
-
- g_aes_sbox[i] = 0;
- for(bi = 0; bi < 8; bi++) {
- // based on transformation 5.1
- // could also be done with a loop based on the matrix
- g_aes_sbox[i] |= ((inv & (1<<bi)?1:0)
- ^ (inv & (1 << ((bi+4) & 7))?1:0)
- ^ (inv & (1 << ((bi+5) & 7))?1:0)
- ^ (inv & (1 << ((bi+6) & 7))?1:0)
- ^ (inv & (1 << ((bi+7) & 7))?1:0)
- ^ (AES_SBOX_CC & (1 << bi)?1:0)
- ) << bi;
- }
- g_aes_isbox[g_aes_sbox[i]] = i;
- }
- // warning: quickhack
- g_aes_sbox[1] = 0x7c;
- g_aes_isbox[0x7c] = 1;
- g_aes_isbox[0x63] = 0;
-}
-
-aes_ctx_t *aes_alloc_ctx(unsigned char *key, size_t keyLen)
-{
- aes_ctx_t *ctx;
- size_t rounds;
- size_t ks_size;
-
- switch(keyLen) {
- case 16: // 128-bit key
- rounds = 10;
- break;
-
- case 24: // 192-bit key
- rounds = 12;
- break;
-
- case 32: // 256-bit key
- rounds = 14;
- break;
-
- default:
- return NULL;
- }
-
- ks_size = 4*(rounds+1)*sizeof(unsigned long);
- ctx = malloc(sizeof(aes_ctx_t)+ks_size);
- if(ctx) {
- ctx->rounds = rounds;
- ctx->kcol = keyLen/4;
- memcpy(ctx->keysched, key, keyLen);
- ctx->keysched[43] = 0;
- aes_keyexpansion(ctx);
- }
-
- return ctx;
-}
-
-inline unsigned long aes_subword(unsigned long w)
-{
- return g_aes_sbox[w & 0x000000ff] |
- (g_aes_sbox[(w & 0x0000ff00) >> 8] << 8) |
- (g_aes_sbox[(w & 0x00ff0000) >> 16] << 16) |
- (g_aes_sbox[(w & 0xff000000) >> 24] << 24);
-}
-
-inline unsigned long aes_rotword(unsigned long w)
-{
- // May seem a bit different from the spec
- // It was changed because unsigned long is represented with little-endian convention on x86
- // Should not depend on architecture, but this is only a POC
- return ((w & 0x000000ff) << 24) |
- ((w & 0x0000ff00) >> 8) |
- ((w & 0x00ff0000) >> 8) |
- ((w & 0xff000000) >> 8);
-}
-
-void aes_keyexpansion(aes_ctx_t *ctx)
-{
- unsigned long temp;
- unsigned long rcon;
- register int i;
-
- rcon = 0x00000001;
- for(i = ctx->kcol; i < (4*(ctx->rounds+1)); i++) {
- temp = ctx->keysched[i-1];
- if(!(i%ctx->kcol)) {
- temp = aes_subword(aes_rotword(temp)) ^ rcon;
- rcon = aes_mul(rcon, 2);
- } else if(ctx->kcol > 6 && i%ctx->kcol == 4)
- temp = aes_subword(temp);
- ctx->keysched[i] = ctx->keysched[i-ctx->kcol] ^ temp;
- }
-}
-
-inline unsigned char aes_mul_manual(unsigned char a, unsigned char b)
-{
- register unsigned short ac;
- register unsigned char ret;
-
- ac = a;
- ret = 0;
- while(b) {
- if(b & 0x01)
- ret ^= ac;
- ac <<= 1;
- b >>= 1;
- if(ac & 0x0100)
- ac ^= AES_RPOL;
- }
-
- return ret;
-}
-
-void aes_subbytes(aes_ctx_t *ctx)
-{
- int i;
-
- for(i = 0; i < 16; i++) {
- int x, y;
-
- x = i & 0x03;
- y = i >> 2;
- ctx->state[x][y] = g_aes_sbox[ctx->state[x][y]];
- }
-}
-
-void aes_shiftrows(aes_ctx_t *ctx)
-{
- unsigned char nstate[4][4];
- int i;
-
- for(i = 0; i < 16; i++) {
- int x, y;
-
- x = i & 0x03;
- y = i >> 2;
- nstate[x][y] = ctx->state[x][(y+x) & 0x03];
- }
-
- memcpy(ctx->state, nstate, sizeof(ctx->state));
-}
-
-void aes_mixcolumns(aes_ctx_t *ctx)
-{
- unsigned char nstate[4][4];
- int i;
-
- for(i = 0; i < 4; i++) {
- nstate[0][i] = aes_mul(0x02, ctx->state[0][i]) ^
- aes_mul(0x03, ctx->state[1][i]) ^
- ctx->state[2][i] ^
- ctx->state[3][i];
- nstate[1][i] = ctx->state[0][i] ^
- aes_mul(0x02, ctx->state[1][i]) ^
- aes_mul(0x03, ctx->state[2][i]) ^
- ctx->state[3][i];
- nstate[2][i] = ctx->state[0][i] ^
- ctx->state[1][i] ^
- aes_mul(0x02, ctx->state[2][i]) ^
- aes_mul(0x03, ctx->state[3][i]);
- nstate[3][i] = aes_mul(0x03, ctx->state[0][i]) ^
- ctx->state[1][i] ^
- ctx->state[2][i] ^
- aes_mul(0x02, ctx->state[3][i]);
- }
-
- memcpy(ctx->state, nstate, sizeof(ctx->state));
-}
-
-void aes_addroundkey(aes_ctx_t *ctx, int round)
-{
- int i;
-
- for(i = 0; i < 16; i++) {
- int x, y;
-
- x = i & 0x03;
- y = i >> 2;
- ctx->state[x][y] = ctx->state[x][y] ^
- ((ctx->keysched[round*4+y] & (0xff << (x*8))) >> (x*8));
- }
-}
-
-void aes_encrypt(aes_ctx_t *ctx, unsigned char input[16], unsigned char output[16])
-{
- int i;
-
- // copy input to state
- for(i = 0; i < 16; i++)
- ctx->state[i & 0x03][i >> 2] = input[i];
-
- aes_addroundkey(ctx, 0);
-
- for(i = 1; i < ctx->rounds; i++) {
- aes_subbytes(ctx);
- aes_shiftrows(ctx);
- aes_mixcolumns(ctx);
- aes_addroundkey(ctx, i);
- }
-
- aes_subbytes(ctx);
- aes_shiftrows(ctx);
- aes_addroundkey(ctx, ctx->rounds);
-
- // copy state to output
- for(i = 0; i < 16; i++)
- output[i] = ctx->state[i & 0x03][i >> 2];
-}
-
-void aes_invshiftrows(aes_ctx_t *ctx)
-{
- unsigned char nstate[4][4];
- int i;
-
- for(i = 0; i < 16; i++) {
- int x, y;
-
- x = i & 0x03;
- y = i >> 2;
- nstate[x][(y+x) & 0x03] = ctx->state[x][y];
- }
-
- memcpy(ctx->state, nstate, sizeof(ctx->state));
-}
-
-void aes_invsubbytes(aes_ctx_t *ctx)
-{
- int i;
-
- for(i = 0; i < 16; i++) {
- int x, y;
-
- x = i & 0x03;
- y = i >> 2;
- ctx->state[x][y] = g_aes_isbox[ctx->state[x][y]];
- }
-}
-
-void aes_invmixcolumns(aes_ctx_t *ctx)
-{
- unsigned char nstate[4][4];
- int i;
-
- for(i = 0; i < 4; i++) {
- nstate[0][i] = aes_mul(0x0e, ctx->state[0][i]) ^
- aes_mul(0x0b, ctx->state[1][i]) ^
- aes_mul(0x0d, ctx->state[2][i]) ^
- aes_mul(0x09, ctx->state[3][i]);
- nstate[1][i] = aes_mul(0x09, ctx->state[0][i]) ^
- aes_mul(0x0e, ctx->state[1][i]) ^
- aes_mul(0x0b, ctx->state[2][i]) ^
- aes_mul(0x0d, ctx->state[3][i]);
- nstate[2][i] = aes_mul(0x0d, ctx->state[0][i]) ^
- aes_mul(0x09, ctx->state[1][i]) ^
- aes_mul(0x0e, ctx->state[2][i]) ^
- aes_mul(0x0b, ctx->state[3][i]);
- nstate[3][i] = aes_mul(0x0b, ctx->state[0][i]) ^
- aes_mul(0x0d, ctx->state[1][i]) ^
- aes_mul(0x09, ctx->state[2][i]) ^
- aes_mul(0x0e, ctx->state[3][i]);
- }
-
- memcpy(ctx->state, nstate, sizeof(ctx->state));
-}
-
-void aes_decrypt(aes_ctx_t *ctx, unsigned char input[16], unsigned char output[16])
-{
- int i;
-
- // copy input to state
- for(i = 0; i < 16; i++)
- ctx->state[i & 0x03][i >> 2] = input[i];
-
- aes_addroundkey(ctx, ctx->rounds);
- for(i = ctx->rounds-1; i >= 1; i--) {
- aes_invshiftrows(ctx);
- aes_invsubbytes(ctx);
- aes_addroundkey(ctx, i);
- aes_invmixcolumns(ctx);
- }
-
- aes_invshiftrows(ctx);
- aes_invsubbytes(ctx);
- aes_addroundkey(ctx, 0);
-
- // copy state to output
- for(i = 0; i < 16; i++)
- output[i] = ctx->state[i & 0x03][i >> 2];
-}
-
-void aes_free_ctx(aes_ctx_t *ctx)
-{
- free(ctx);
-}
-
-#define PRINT_BYTES(bPtr, siz, offset) { int _bPtr_idx; for (_bPtr_idx = offset; _bPtr_idx < offset+siz; _bPtr_idx++) { printf("%02X ", bPtr[_bPtr_idx]); } printf("\n"); }
-int main(int argc, char *argv[])
-{
- if (argc != 3) {
- fprintf(stderr, "usage: %s [KEY] [MSG]\n", argv[0]);
- return 1;
- }
-
- size_t klen = strlen(argv[1]);
- unsigned char key[KEY_128];
- memcpy(key, argv[1], klen);
-
- size_t plen = strlen(argv[2]);
- unsigned char ptext[plen+1];
- memcpy(ptext, argv[2], plen);
- ptext[plen] = '\0';
-
- unsigned char ctext[plen+1];
- memset(ctext, '\0', plen+1);
- unsigned char decptext[plen+1];
- memset(decptext, '\0', plen+1);
-
- aes_ctx_t *ctx;
-
- init_aes();
- ctx = aes_alloc_ctx(key, sizeof(key));
- if(!ctx) {
- perror("aes_alloc_ctx");
- return EXIT_FAILURE;
- }
- printf("Encrypted[HEX]..: ");
- aes_encrypt(ctx, ptext, ctext);
- PRINT_BYTES(ctext, sizeof(ctext), 0);
- aes_decrypt(ctx, ctext, decptext);
- printf("Decrypted[HEX]..: ");
- PRINT_BYTES(decptext, sizeof(decptext), 0);
- printf("Decrypted[ASCII]: ");
- puts((char*)decptext);
-
- aes_free_ctx(ctx);
- return EXIT_SUCCESS;
-}
-