summaryrefslogtreecommitdiff
path: root/src/hmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hmac.c')
-rw-r--r--src/hmac.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/hmac.c b/src/hmac.c
new file mode 100644
index 0000000..bf624db
--- /dev/null
+++ b/src/hmac.c
@@ -0,0 +1,114 @@
+/*
+ * hmac.c: routines to compute HMAC-SHA-1/224/256/384/512 digests
+ *
+ * Ref: FIPS PUB 198 The Keyed-Hash Message Authentication Code
+ *
+ * Copyright (C) 2003-2005 Mark Shelor, All Rights Reserved
+ *
+ * Version: 5.31
+ * Mon Sep 5 00:52:42 MST 2005
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "hmac.h"
+#include "sha.h"
+
+/* hmacopen: creates a new HMAC-SHA digest object */
+HMAC *hmacopen(alg, key, keylen)
+int alg;
+unsigned char *key;
+unsigned int keylen;
+{
+ int i;
+ HMAC *h;
+
+ SHA_newz(0, h, 1, HMAC);
+ if (h == NULL)
+ return(NULL);
+ if ((h->isha = shaopen(alg)) == NULL) {
+ SHA_free(h);
+ return(NULL);
+ }
+ if ((h->osha = shaopen(alg)) == NULL) {
+ shaclose(h->isha);
+ SHA_free(h);
+ return(NULL);
+ }
+ if (keylen <= h->osha->blocksize / 8)
+ memcpy(h->key, key, keylen);
+ else {
+ if ((h->ksha = shaopen(alg)) == NULL) {
+ shaclose(h->isha);
+ shaclose(h->osha);
+ SHA_free(h);
+ return(NULL);
+ }
+ shawrite(key, keylen * 8, h->ksha);
+ shafinish(h->ksha);
+ memcpy(h->key, shadigest(h->ksha), h->ksha->digestlen);
+ shaclose(h->ksha);
+ }
+ for (i = 0; i < h->osha->blocksize / 8; i++)
+ h->key[i] ^= 0x5c;
+ shawrite(h->key, h->osha->blocksize, h->osha);
+ for (i = 0; i < h->isha->blocksize / 8; i++)
+ h->key[i] ^= (0x5c ^ 0x36);
+ shawrite(h->key, h->isha->blocksize, h->isha);
+ memset(h->key, 0, sizeof(h->key));
+ return(h);
+}
+
+/* hmacwrite: triggers a state update using data in bitstr/bitcnt */
+unsigned long hmacwrite(bitstr, bitcnt, h)
+unsigned char *bitstr;
+unsigned long bitcnt;
+HMAC *h;
+{
+ return(shawrite(bitstr, bitcnt, h->isha));
+}
+
+/* hmacfinish: computes final digest state */
+void hmacfinish(h)
+HMAC *h;
+{
+ shafinish(h->isha);
+ shawrite(shadigest(h->isha), h->isha->digestlen * 8, h->osha);
+ shaclose(h->isha);
+ shafinish(h->osha);
+}
+
+/* hmacdigest: returns pointer to digest (binary) */
+unsigned char *hmacdigest(h)
+HMAC *h;
+{
+ return(shadigest(h->osha));
+}
+
+/* hmachex: returns pointer to digest (hexadecimal) */
+char *hmachex(h)
+HMAC *h;
+{
+ return(shahex(h->osha));
+}
+
+/* hmacbase64: returns pointer to digest (Base 64) */
+char *hmacbase64(h)
+HMAC *h;
+{
+ return(shabase64(h->osha));
+}
+
+/* hmacclose: de-allocates digest object */
+int hmacclose(h)
+HMAC *h;
+{
+ shaclose(h->osha);
+ if (h != NULL) {
+ memset(h, 0, sizeof(HMAC));
+ SHA_free(h);
+ }
+ return(0);
+}