diff options
author | George McCollister <George.McCollister@gmail.com> | 2012-06-19 12:36:28 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-06-26 09:01:26 -0400 |
commit | e07a94a66985b674c5df11ca466792902164c4e2 (patch) | |
tree | f6e3443b5665c2a73f56a6dde999f21d25338473 /src/util/crypto/libcrypto/crypto_hmac_sha1.c | |
parent | 9dadbd5cac8b25a198633508a27747039be43c34 (diff) | |
download | sssd-e07a94a66985b674c5df11ca466792902164c4e2.tar.gz sssd-e07a94a66985b674c5df11ca466792902164c4e2.tar.bz2 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.c | 60 |
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 32acd25a..37d25794 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; } |