summaryrefslogtreecommitdiffstats
path: root/src/util/crypto/libcrypto/crypto_hmac_sha1.c
diff options
context:
space:
mode:
authorGeorge McCollister <George.McCollister@gmail.com>2012-06-19 12:36:28 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-06-26 09:01:26 -0400
commite07a94a66985b674c5df11ca466792902164c4e2 (patch)
treef6e3443b5665c2a73f56a6dde999f21d25338473 /src/util/crypto/libcrypto/crypto_hmac_sha1.c
parent9dadbd5cac8b25a198633508a27747039be43c34 (diff)
downloadsssd-e07a94a66985b674c5df11ca466792902164c4e2.tar.gz
sssd-e07a94a66985b674c5df11ca466792902164c4e2.tar.xz
sssd-e07a94a66985b674c5df11ca466792902164c4e2.zip
libcrypto fully implemented
Implemented working versions of the following functions for libcrypto: sss_base64_encode sss_base64_decode sss_hmac_sha1 sss_password_encrypt sss_password_decrypt test_encrypt_decrypt now expects EOK from libcrypto. test_hmac_sha1 now expects EOK from libcrypto. Added test_base64_encode to test base64 encoding implementation. Added test_base64_decode to test base64 decoding implementation. Signed-off-by: George McCollister <George.McCollister@gmail.com>
Diffstat (limited to 'src/util/crypto/libcrypto/crypto_hmac_sha1.c')
-rw-r--r--src/util/crypto/libcrypto/crypto_hmac_sha1.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/util/crypto/libcrypto/crypto_hmac_sha1.c b/src/util/crypto/libcrypto/crypto_hmac_sha1.c
index 32acd25ac..37d25794e 100644
--- a/src/util/crypto/libcrypto/crypto_hmac_sha1.c
+++ b/src/util/crypto/libcrypto/crypto_hmac_sha1.c
@@ -1,6 +1,7 @@
/*
Authors:
Jan Cholasta <jcholast@redhat.com>
+ George McCollister <george.mccollister@gmail.com>
Copyright (C) 2012 Red Hat
@@ -19,6 +20,11 @@
*/
#include "util/util.h"
+#include "util/crypto/sss_crypto.h"
+
+#include <openssl/evp.h>
+
+#define HMAC_SHA1_BLOCKSIZE 64
int sss_hmac_sha1(const unsigned char *key,
size_t key_len,
@@ -26,6 +32,56 @@ int sss_hmac_sha1(const unsigned char *key,
size_t in_len,
unsigned char *out)
{
- DEBUG(SSSDBG_CRIT_FAILURE, ("sss_hmac_sha1 not implemented.\n"));
- return ENOSYS;
+ int ret;
+ EVP_MD_CTX ctx;
+ unsigned char ikey[HMAC_SHA1_BLOCKSIZE], okey[HMAC_SHA1_BLOCKSIZE];
+ size_t i;
+ unsigned char hash[SSS_SHA1_LENGTH];
+ unsigned int res_len;
+
+ EVP_MD_CTX_init(&ctx);
+
+ if (key_len > HMAC_SHA1_BLOCKSIZE) {
+ /* keys longer than blocksize are shortened */
+ if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) {
+ ret = EIO;
+ goto done;
+ }
+
+ EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len);
+ EVP_DigestFinal_ex(&ctx, ikey, &res_len);
+ memset(ikey + SSS_SHA1_LENGTH, 0, HMAC_SHA1_BLOCKSIZE - SSS_SHA1_LENGTH);
+ } else {
+ /* keys shorter than blocksize are zero-padded */
+ memcpy(ikey, key, key_len);
+ memset(ikey + key_len, 0, HMAC_SHA1_BLOCKSIZE - key_len);
+ }
+
+ /* HMAC(key, msg) = HASH(key XOR opad, HASH(key XOR ipad, msg)) */
+ for (i = 0; i < HMAC_SHA1_BLOCKSIZE; i++) {
+ okey[i] = ikey[i] ^ 0x5c;
+ ikey[i] ^= 0x36;
+ }
+
+ if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) {
+ ret = EIO;
+ goto done;
+ }
+
+ EVP_DigestUpdate(&ctx, (const unsigned char *)ikey, HMAC_SHA1_BLOCKSIZE);
+ EVP_DigestUpdate(&ctx, (const unsigned char *)in, in_len);
+ EVP_DigestFinal_ex(&ctx, hash, &res_len);
+
+ if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) {
+ ret = EIO;
+ goto done;
+ }
+
+ EVP_DigestUpdate(&ctx, (const unsigned char *)okey, HMAC_SHA1_BLOCKSIZE);
+ EVP_DigestUpdate(&ctx, (const unsigned char *)hash, SSS_SHA1_LENGTH);
+ EVP_DigestFinal_ex(&ctx, out, &res_len);
+ ret = EOK;
+done:
+ EVP_MD_CTX_cleanup(&ctx);
+ return ret;
}