mirror of
https://github.com/sheumann/65816-crypto.git
synced 2024-11-24 04:31:18 +00:00
Implement HMAC-MD5, HMAC-SHA1, and HMAC-SHA256.
This commit is contained in:
parent
4f7c6c0eb8
commit
c1e1caa766
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2017 Stephen Heumann
|
||||
Copyright (c) 2017,2023 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
|
||||
|
13
Makefile
13
Makefile
@ -4,7 +4,7 @@ CFLAGS = -O255 -w255
|
||||
LIBRARIES = lib65816crypto lib65816hash
|
||||
|
||||
PROGRAMS = aescbctest aesctrtest aestest aescrypt sha1sum sha1test \
|
||||
sha256sum sha256test md5sum md5test
|
||||
sha256sum sha256test md5sum md5test hmactest
|
||||
|
||||
.PHONY: default
|
||||
default: $(LIBRARIES) $(PROGRAMS)
|
||||
@ -21,15 +21,15 @@ aes.a: aes.asm aes.macros
|
||||
mv aes.A aes.a
|
||||
|
||||
# Hash algorithms
|
||||
sha1.a: sha1.cc sha1.h sha1.asm sha1.macros
|
||||
sha1.a: sha1.cc sha1.h sha1.asm sha1.macros hmacimpl.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
sha1.B: sha1.a
|
||||
|
||||
sha256.a: sha256.cc sha1.h sha256.asm sha1.macros
|
||||
sha256.a: sha256.cc sha256.h sha256.asm sha256.macros hmacimpl.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
sha256.B: sha256.a
|
||||
|
||||
md5.a: md5.cc md5.h md5.asm md5.macros
|
||||
md5.a: md5.cc md5.h md5.asm md5.macros hmacimpl.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
md5.B: md5.a
|
||||
|
||||
@ -66,6 +66,9 @@ md5sum.a: md5sum.c md5.h cksumcommon.h
|
||||
md5test.a: md5test.c md5.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
hmactest.a: hmactest.c sha256.h sha1.h md5.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
aescbctest: aescbctest.a pagealign.root lib65816crypto
|
||||
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816crypto -o $@
|
||||
aesctrtest: aesctrtest.a pagealign.root lib65816crypto
|
||||
@ -90,6 +93,8 @@ md5sum: md5sum.a pagealign.root lib65816hash
|
||||
md5test: md5test.a pagealign.root lib65816hash
|
||||
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816hash -o $@
|
||||
|
||||
hmactest: hmactest.a lib65816hash
|
||||
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816hash -o $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
87
hmacimpl.h
Normal file
87
hmacimpl.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is a template for computing HMACs using the hash functions
|
||||
* from lib65816hash. It is #included from the files implementing the
|
||||
* hash functions, with HASH_ALG defined to the name of the hash function.
|
||||
*/
|
||||
|
||||
#define join(a,b) a##b
|
||||
#define concat(a,b) join(a,b)
|
||||
|
||||
#define join3(a,b,c) a##b##c
|
||||
#define concat3(a,b,c) join3(a,b,c)
|
||||
|
||||
#define hash_init concat(HASH_ALG,_init)
|
||||
#define hash_update concat(HASH_ALG,_update)
|
||||
#define hash_finalize concat(HASH_ALG,_finalize)
|
||||
|
||||
#define hmac_init concat3(hmac_,HASH_ALG,_init)
|
||||
#define hmac_compute concat3(hmac_,HASH_ALG,_compute)
|
||||
#define hmac_context concat3(hmac_,HASH_ALG,_context)
|
||||
|
||||
void hmac_init(struct hmac_context *context,
|
||||
const unsigned char *key,
|
||||
unsigned long key_length)
|
||||
{
|
||||
#define BLOCK_SIZE sizeof(context->u[0].ctx.block)
|
||||
#define HASH_SIZE sizeof(context->u[0].ctx.hash)
|
||||
|
||||
unsigned i;
|
||||
|
||||
// Compute adjusted key (hashed from original key if necessary)
|
||||
memset(context->u[0].k, 0, BLOCK_SIZE);
|
||||
if (key_length <= BLOCK_SIZE) {
|
||||
memcpy(context->u[0].k, key, key_length);
|
||||
} else {
|
||||
hash_init(&context->u[1].ctx);
|
||||
hash_update(&context->u[1].ctx, key, key_length);
|
||||
hash_finalize(&context->u[1].ctx);
|
||||
memcpy(context->u[0].k, context->u[1].ctx.hash, HASH_SIZE);
|
||||
}
|
||||
|
||||
// Set context->u[0].k to K XOR opad, context->u[1].k to K XOR ipad
|
||||
for (i = 0; i < BLOCK_SIZE; i++) {
|
||||
context->u[1].k[i] = context->u[0].k[i] ^ 0x36;
|
||||
context->u[0].k[i] ^= 0x5C;
|
||||
}
|
||||
|
||||
// Save inner hash context following initial block as context->u[2].ctx
|
||||
hash_init(&context->u[2].ctx);
|
||||
hash_update(&context->u[2].ctx, context->u[1].k, BLOCK_SIZE);
|
||||
|
||||
// Save outer hash context following initial block as context->u[1].ctx
|
||||
hash_init(&context->u[1].ctx);
|
||||
hash_update(&context->u[1].ctx, context->u[0].k, BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
void hmac_compute(struct hmac_context *context,
|
||||
const unsigned char *message,
|
||||
unsigned long message_length)
|
||||
{
|
||||
// Compute inner hash
|
||||
context->u[0].ctx = context->u[2].ctx;
|
||||
hash_update(&context->u[0].ctx, message, message_length);
|
||||
hash_finalize(&context->u[0].ctx);
|
||||
memcpy(context->inner_hash, context->u[0].ctx.hash, HASH_SIZE);
|
||||
|
||||
// Compute outer hash
|
||||
context->u[0].ctx = context->u[1].ctx;
|
||||
hash_update(&context->u[0].ctx, context->inner_hash, HASH_SIZE);
|
||||
hash_finalize(&context->u[0].ctx);
|
||||
}
|
71
hmactest.c
Normal file
71
hmactest.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 <orca.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "sha256.h"
|
||||
#include "sha1.h"
|
||||
#include "md5.h"
|
||||
|
||||
int main(void) {
|
||||
Handle context_hndl;
|
||||
struct hmac_sha256_context *hmac_sha256_context;
|
||||
struct hmac_sha1_context *hmac_sha1_context;
|
||||
struct hmac_md5_context *hmac_md5_context;
|
||||
|
||||
char key[] = "key";
|
||||
char msg[] = "The quick brown fox jumps over the lazy dog";
|
||||
|
||||
context_hndl = NewHandle(sizeof(struct hmac_sha256_context),
|
||||
userid(), attrFixed|attrPage|attrBank|attrNoCross, 0x000000);
|
||||
if (toolerror())
|
||||
return 0;
|
||||
|
||||
|
||||
hmac_sha256_context = (struct hmac_sha256_context *)*context_hndl;
|
||||
hmac_sha256_init(hmac_sha256_context, key, sizeof(key)-1);
|
||||
hmac_sha256_compute(hmac_sha256_context, msg, sizeof(msg)-1);
|
||||
|
||||
printf("HMAC-SHA256: ");
|
||||
for (int i = 0; i < sizeof(hmac_sha256_context->u[0].ctx.hash); i++) {
|
||||
printf("%02x", hmac_sha256_context->u[0].ctx.hash[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
hmac_sha1_context = (struct hmac_sha1_context *)*context_hndl;
|
||||
hmac_sha1_init(hmac_sha1_context, key, sizeof(key)-1);
|
||||
hmac_sha1_compute(hmac_sha1_context, msg, sizeof(msg)-1);
|
||||
|
||||
printf("HMAC-SHA1: ");
|
||||
for (int i = 0; i < sizeof(hmac_sha1_context->u[0].ctx.hash); i++) {
|
||||
printf("%02x", hmac_sha1_context->u[0].ctx.hash[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
hmac_md5_context = (struct hmac_md5_context *)*context_hndl;
|
||||
hmac_md5_init(hmac_md5_context, key, sizeof(key)-1);
|
||||
hmac_md5_compute(hmac_md5_context, msg, sizeof(msg)-1);
|
||||
|
||||
printf("HMAC-MD5: ");
|
||||
for (int i = 0; i < sizeof(hmac_md5_context->u[0].ctx.hash); i++) {
|
||||
printf("%02x", hmac_md5_context->u[0].ctx.hash[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
5
md5.cc
5
md5.cc
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Stephen Heumann
|
||||
* Copyright (c) 2017,2023 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
|
||||
@ -135,4 +135,7 @@ void md5_finalize(struct md5_context *context)
|
||||
}
|
||||
}
|
||||
|
||||
#define HASH_ALG md5
|
||||
#include "hmacimpl.h"
|
||||
|
||||
#append "md5.asm"
|
||||
|
28
md5.h
28
md5.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Stephen Heumann
|
||||
* Copyright (c) 2017,2023 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
|
||||
@ -24,6 +24,14 @@ struct md5_context {
|
||||
unsigned char block[64];
|
||||
};
|
||||
|
||||
struct hmac_md5_context {
|
||||
union {
|
||||
struct md5_context ctx;
|
||||
unsigned char k[64];
|
||||
} u[3];
|
||||
unsigned char inner_hash[16];
|
||||
};
|
||||
|
||||
/*
|
||||
* The context structure must be in bank 0, preferably page-aligned.
|
||||
*/
|
||||
@ -49,3 +57,21 @@ void md5_finalize(struct md5_context *context);
|
||||
* This is a low-level function; users should normally not call this directly.
|
||||
*/
|
||||
void md5_processblock(struct md5_context *context);
|
||||
|
||||
/*
|
||||
* Initialize a context for HMAC-MD5 computation with a specified key.
|
||||
* This must be called before any calls to hmac_md5_compute. After
|
||||
* initialization, the context can be used to compute the HMAC for any
|
||||
* number of messages.
|
||||
*/
|
||||
void hmac_md5_init(struct hmac_md5_context *context,
|
||||
const unsigned char *key,
|
||||
unsigned long key_length);
|
||||
|
||||
/*
|
||||
* Compute the HMAC-MD5 of a message, using an already-initialized context.
|
||||
* The result will be in context->u[0].ctx.hash.
|
||||
*/
|
||||
void hmac_md5_compute(struct hmac_md5_context *context,
|
||||
const unsigned char *message,
|
||||
unsigned long message_length);
|
||||
|
5
sha1.cc
5
sha1.cc
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Stephen Heumann
|
||||
* Copyright (c) 2017,2023 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
|
||||
@ -180,4 +180,7 @@ void sha1_finalize(struct sha1_context *context)
|
||||
}
|
||||
}
|
||||
|
||||
#define HASH_ALG sha1
|
||||
#include "hmacimpl.h"
|
||||
|
||||
#append "sha1.asm"
|
||||
|
28
sha1.h
28
sha1.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Stephen Heumann
|
||||
* Copyright (c) 2017,2023 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
|
||||
@ -24,6 +24,14 @@ struct sha1_context {
|
||||
unsigned char reserved2[16];
|
||||
};
|
||||
|
||||
struct hmac_sha1_context {
|
||||
union {
|
||||
struct sha1_context ctx;
|
||||
unsigned char k[64];
|
||||
} u[3];
|
||||
unsigned char inner_hash[20];
|
||||
};
|
||||
|
||||
/*
|
||||
* The context structure must be in bank 0, preferably page-aligned.
|
||||
*/
|
||||
@ -49,3 +57,21 @@ void sha1_finalize(struct sha1_context *context);
|
||||
* This is a low-level function; users should normally not call this directly.
|
||||
*/
|
||||
void sha1_processblock(struct sha1_context *context);
|
||||
|
||||
/*
|
||||
* Initialize a context for HMAC-SHA1 computation with a specified key.
|
||||
* This must be called before any calls to hmac_sha1_compute. After
|
||||
* initialization, the context can be used to compute the HMAC for any
|
||||
* number of messages.
|
||||
*/
|
||||
void hmac_sha1_init(struct hmac_sha1_context *context,
|
||||
const unsigned char *key,
|
||||
unsigned long key_length);
|
||||
|
||||
/*
|
||||
* Compute the HMAC-SHA1 of a message, using an already-initialized context.
|
||||
* The result will be in context->u[0].ctx.hash.
|
||||
*/
|
||||
void hmac_sha1_compute(struct hmac_sha1_context *context,
|
||||
const unsigned char *message,
|
||||
unsigned long message_length);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Stephen Heumann
|
||||
* Copyright (c) 2017,2023 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
|
||||
@ -204,4 +204,7 @@ void sha256_finalize(struct sha256_context *context)
|
||||
}
|
||||
}
|
||||
|
||||
#define HASH_ALG sha256
|
||||
#include "hmacimpl.h"
|
||||
|
||||
#append "sha256.asm"
|
||||
|
28
sha256.h
28
sha256.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Stephen Heumann
|
||||
* Copyright (c) 2017,2023 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
|
||||
@ -24,6 +24,14 @@ struct sha256_context {
|
||||
unsigned char reserved2[60];
|
||||
};
|
||||
|
||||
struct hmac_sha256_context {
|
||||
union {
|
||||
struct sha256_context ctx;
|
||||
unsigned char k[64];
|
||||
} u[3];
|
||||
unsigned char inner_hash[32];
|
||||
};
|
||||
|
||||
/*
|
||||
* The context structure must be in bank 0, preferably page-aligned.
|
||||
*/
|
||||
@ -57,3 +65,21 @@ void sha256_finalize(struct sha256_context *context);
|
||||
* This is a low-level function; users should normally not call this directly.
|
||||
*/
|
||||
void sha256_processblock(struct sha256_context *context);
|
||||
|
||||
/*
|
||||
* Initialize a context for HMAC-SHA256 computation with a specified key.
|
||||
* This must be called before any calls to hmac_sha256_compute. After
|
||||
* initialization, the context can be used to compute the HMAC for any
|
||||
* number of messages.
|
||||
*/
|
||||
void hmac_sha256_init(struct hmac_sha256_context *context,
|
||||
const unsigned char *key,
|
||||
unsigned long key_length);
|
||||
|
||||
/*
|
||||
* Compute the HMAC-SHA256 of a message, using an already-initialized context.
|
||||
* The result will be in context->u[0].ctx.hash.
|
||||
*/
|
||||
void hmac_sha256_compute(struct hmac_sha256_context *context,
|
||||
const unsigned char *message,
|
||||
unsigned long message_length);
|
||||
|
Loading…
Reference in New Issue
Block a user