From 740b870a7a4d1936991d856f5427e4c10c2c849a Mon Sep 17 00:00:00 2001 From: Eugene Crosser Date: Thu, 31 Oct 2013 00:06:22 +0400 Subject: [PATCH] crypto iface compiles --- configure.ac | 2 ++ crypto.c | 48 +++++++++++++++++++++++------ crypto.h | 11 ++++--- crypto_if.h | 15 ++++----- ossl_crypto.c | 84 ++++++++++++++++++++++++++++++++++----------------- pcsc_cr.c | 6 ++-- token.h | 8 ++--- tom_crypto.c | 62 ++++++++++++++++++++++++++----------- ykneo.c | 8 ++--- 9 files changed, 168 insertions(+), 76 deletions(-) diff --git a/configure.ac b/configure.ac index 02169b4..1e6cdfa 100644 --- a/configure.ac +++ b/configure.ac @@ -73,9 +73,11 @@ AS_IF([test "x$use_openssl" != "xyes" -a "x$use_tomcrypt" != "xyes"], [ AS_IF([test "x$use_openssl" = "xyes"], [ CRYPTO_OBJS+=" ossl_crypto.lo" + AC_DEFINE([HAVE_OPENSSL], [1], [Use openssl libcrypto]) ]) AS_IF([test "x$use_tomcrypt" = "xyes"], [ CRYPTO_OBJS+=" tom_crypto.lo" + AC_DEFINE([HAVE_TOMCRYPT], [1], [Use libtomcrypt]) ]) AC_SUBST(CRYPTO_OBJS) diff --git a/crypto.c b/crypto.c index 83ba4ef..282a713 100644 --- a/crypto.c +++ b/crypto.c @@ -1,28 +1,58 @@ +#include #include "crypto.h" #include "crypto_if.h" extern struct crypto_interface ossl_crypto_if; extern struct crypto_interface tom_crypto_if; -static struct crypto_interface *active = &ossl_crypto_if; +static struct crypto_interface *ifs[] = { +#ifdef HAVE_OPENSSL + &ossl_crypto_if, +#endif +#ifdef HAVE_TOMCRYPT + &tom_crypto_if, +#endif + (void*)0, +}; +#define MAX_IF (sizeof(ifs)/sizeof(struct crypto_interface *)-2) -int encrypt(void *pt, int ptlen, void *key, int keylen, void *ct, int *ctlen) +static int which = 0; + +int select_crypto_if(int ifno) { - return active->encrypt(pt, ptlen, key, keylen, ct, ctlen); + if (ifno < 0 || ifno > MAX_IF) return -1; + which = ifno; + return 0; } -int decrypt(void *ct, int ctlen, void *key, int keylen, void *pt, int *ptlen) +static unsigned char iv[16] = {0}; + +unsigned long encrypt(void *key, int keylen, void *pt, void *ct, int tlen) { - return active->decrypt(ct, ctlen, key, keylen, pt, ptlen); + assert(keylen == 16); + return ifs[which]->encrypt(key, keylen, iv, pt, ct, tlen); } -int hash(void *pt, int ptlen, void *tag, int *taglen) +unsigned long decrypt(void *key, int keylen, void *ct, void *pt, int tlen) { - return active->hash(pt, ptlen, tag, taglen); + assert(keylen == 16); + return ifs[which]->decrypt(key, keylen, iv, ct, pt, tlen); } -int hmac(void *pt, int ptlen, void *key, int keylen, void *tag, int *taglen) +unsigned long hash(void *pt, int tlen, void *tag, int *taglen) { - return active->hmac(pt, ptlen, key, keylen, tag, taglen); + assert(*taglen == 20); + return ifs[which]->hash(pt, tlen, tag, taglen); } +unsigned long hmac(void *key, int keylen, void *pt, int tlen, void *tag, int *taglen) +{ + assert(keylen == 20); + assert(*taglen == 20); + return ifs[which]->hmac(key, keylen, pt, tlen, tag, taglen); +} + +const char *crypto_errstr(unsigned long err) +{ + return ifs[which]->errstr(err); +} diff --git a/crypto.h b/crypto.h index 8eaf939..06d7cd5 100644 --- a/crypto.h +++ b/crypto.h @@ -1,9 +1,12 @@ #ifndef _CRYPTO_H #define _CRYPTO_H -int encrypt(void *pt, int ptlen, void *key, int keylen, void *ct, int *ctlen); -int decrypt(void *ct, int ctlen, void *key, int keylen, void *pt, int *ptlen); -int hash(void *pt, int ptlen, void *tag, int *taglen); -int hmac(void *pt, int ptlen, void *key, int keylen, void *tag, int *taglen); +int select_crypto_if(int ifno); +unsigned long encrypt(void *key, int keylen, void *pt, void *ct, int tlen); +unsigned long decrypt(void *key, int keylen, void *ct, void *pt, int tlen); +unsigned long hash(void *pt, int tlen, void *tag, int *taglen); +unsigned long hmac(void *key, int keylen, void *pt, int tlen, + void *tag, int *taglen); +const char *crypto_errstr(unsigned long err); #endif diff --git a/crypto_if.h b/crypto_if.h index 488a0e6..c24d6a3 100644 --- a/crypto_if.h +++ b/crypto_if.h @@ -3,13 +3,14 @@ struct crypto_interface { char *name; - int (*encrypt)(void *pt, int ptlen, void *key, int keylen, - void *ct, int *ctlen); - int (*decrypt)(void *ct, int ctlen, void *key, int keylen, - void *pt, int *ptlen); - int (*hash)(void *pt, int ptlen, void *tag, int *taglen); - int (*hmac)(void *ct, int ctlen, void *key, int keylen, - void *tag, int *taglen); + unsigned long (*encrypt)(void *key, int keylen, void *iv, + void *pt, void *ct, int tlen); + unsigned long (*decrypt)(void *key, int keylen, void *iv, + void *ct, void *pt, int tlen); + unsigned long (*hash)(void *pt, int tlen, void *tag, int *taglen); + unsigned long (*hmac)(void *key, int keylen, + void *pt, int tlen, void *tag, int *taglen); + const char *(*errstr)(unsigned long err); }; #endif diff --git a/ossl_crypto.c b/ossl_crypto.c index 61c6504..a7fc515 100644 --- a/ossl_crypto.c +++ b/ossl_crypto.c @@ -1,48 +1,77 @@ +#include +#include #include #include #include "crypto_if.h" -static int ossl_encrypt(void *pt, int ptlen, void *key, int keylen, - void *ct, int *ctlen) +static unsigned long ossl_encrypt(void *key, int keylen, void *iv, + void *pt, void *ct, int tlen) { - EVP_CIPHER_CTX ctx; - unsigned char iv[16] = {0}; - int outlen1, outlen2; + EVP_CIPHER_CTX ctx; + int outlen1, outlen2; + unsigned char hkey[16]; - EVP_EncryptInit(&ctx, EVP_aes_256_cbc(), key, iv); - EVP_EncryptUpdate(&ctx, ct, &outlen1, pt, ptlen); - EVP_EncryptFinal(&ctx, ct + outlen1, &outlen2); - if (outlen1 + outlen2 > *ctlen) return -1; - *ctlen = outlen1 + outlen2; - - return 0; + if (EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), + NULL, key, keylen, 5, hkey, NULL) != 16) return 1UL; + if (!EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), hkey, iv)) + return ERR_get_error(); + if (!EVP_EncryptUpdate(&ctx, ct, &outlen1, pt, tlen)) + return ERR_get_error(); + if (!EVP_EncryptFinal(&ctx, ct + outlen1, &outlen2)) + return ERR_get_error(); + if (outlen1 + outlen2 != tlen) return 1UL; + return 0UL; } -static int ossl_decrypt() +static unsigned long ossl_decrypt(void *key, int keylen, void *iv, + void *ct, void *pt, int tlen) { - return 0; + EVP_CIPHER_CTX ctx; + int outlen1, outlen2; + unsigned char hkey[16]; + + if (EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), + NULL, key, keylen, 5, hkey, NULL) != 16) return 1UL; + if (!EVP_DecryptInit(&ctx, EVP_aes_128_cbc(), hkey, iv)) + return ERR_get_error(); + if (!EVP_DecryptUpdate(&ctx, ct, &outlen1, pt, tlen)) + return ERR_get_error(); + if (!EVP_DecryptFinal(&ctx, ct + outlen1, &outlen2)) + return ERR_get_error(); + if (outlen1 + outlen2 != tlen) return 1UL; + return 0UL; } -static int ossl_hash() +static unsigned long ossl_hash(void *pt, int tlen, void *tag, int *taglen) { - return 0; + SHA_CTX sctx; + + if (!SHA1_Init(&sctx)) return ERR_get_error(); + if (!SHA1_Update(&sctx, pt, tlen)) return ERR_get_error(); + if (!SHA1_Final(tag, &sctx)) return ERR_get_error(); + *taglen = 160; + return 0UL; } -static int ossl_hmac() +static unsigned long ossl_hmac(void *pt, int tlen, void *key, int keylen, + void *tag, int *taglen) { - return 0; -} + HMAC_CTX hctx; -// result = HMAC(EVP_sha256(), key, 999, data, 888, NULL, NULL); -// EVP_MD * + HMAC_CTX_init(&hctx); + if (!HMAC_Init(&hctx, key, keylen, EVP_sha1())) return ERR_get_error(); + if (!HMAC_Update(&hctx, pt, tlen)) return ERR_get_error(); + if (!HMAC_Final(&hctx, tag, (unsigned int *)taglen)) + return ERR_get_error(); + HMAC_CTX_cleanup(&hctx); + return 0UL; +} -// HMAC_CTX hctx; -// HMAC_CTX_init(&hctx); -// if (HMAC_Init(&hctx, key, keylen, EVP_sha1())) success; -// if (HMAC_Update(&hctx, data, datalen)) success; -// if (HMAC_Final(&hctx, &digest, &digestlen)) success -// HMAC_CTX_cleanup(&hctx); +static const char *ossl_errstr(unsigned long err) +{ + return ERR_error_string(err, NULL); +} struct crypto_interface ossl_crypto_if = { .name = "openssl", @@ -50,4 +79,5 @@ struct crypto_interface ossl_crypto_if = { .decrypt = ossl_decrypt, .hash = ossl_hash, .hmac = ossl_hmac, + .errstr = ossl_errstr, }; diff --git a/pcsc_cr.c b/pcsc_cr.c index 50d67f1..03a05d0 100644 --- a/pcsc_cr.c +++ b/pcsc_cr.c @@ -78,17 +78,17 @@ long pcsc_cr(unsigned char *chal, int csize, unsigned char *resp, int *rsize) if (rc == 0) break; } if (rc) goto disconnect; - rc = type->prologue(hCard, NULL); + rc = type->prologue(hCard); if (rc == 0) break; disconnect: (void)SCardDisconnect(hCard, SCARD_LEAVE_CARD); } if (rc) goto free_out; lrsize = *rsize; - rc = type->trancieve(hCard, NULL, chal, csize, resp, &lrsize); + rc = type->trancieve(hCard, chal, csize, resp, &lrsize); if (rc) goto disc_free_out; *rsize = lrsize; - rc = type->epilogue(hCard, NULL); + rc = type->epilogue(hCard); disc_free_out: (void)SCardDisconnect(hCard, SCARD_EJECT_CARD); free_out: diff --git a/token.h b/token.h index e32e3be..b1ef461 100644 --- a/token.h +++ b/token.h @@ -9,10 +9,10 @@ struct token_interface { char *name; int (*parse_option)(char *key, char *val); DWORD (*check_atr_hb)(BYTE *str, DWORD size); - DWORD (*prologue)(SCARDHANDLE hCard,LPTSTR envp[]); - DWORD (*trancieve)(SCARDHANDLE hCard,LPTSTR envp[], - LPTSTR send, DWORD sendsize, BYTE *recv, LPDWORD recvsize_p); - DWORD (*epilogue)(SCARDHANDLE hCard,LPTSTR envp[]); + DWORD (*prologue)(SCARDHANDLE hCard); + DWORD (*trancieve)(SCARDHANDLE hCard, + BYTE *send, DWORD sendsize, BYTE *recv, LPDWORD recvsize_p); + DWORD (*epilogue)(SCARDHANDLE hCard); }; #endif diff --git a/tom_crypto.c b/tom_crypto.c index 79bd202..97a18e1 100644 --- a/tom_crypto.c +++ b/tom_crypto.c @@ -2,40 +2,65 @@ #include "crypto_if.h" -static int tom_encrypt(void *pt, int ptlen, void *key, int keylen, - void *ct, int *ctlen) +static unsigned long tom_encrypt(void *key, int keylen, void *iv, + void *pt, void *ct, int tlen) { symmetric_CBC cbc; - unsigned char iv[16] = {0}; int index, err; - if ((index = register_cipher(&aes_desc)) == -1) return -1; - // if ((index = find_cipher("aes")) == -1) return -1; - // cipher = cipher_descriptor[index]; + if ((index = register_cipher(&aes_desc)) == -1) + return CRYPT_INVALID_CIPHER; if ((err = cbc_start(index, iv, key, keylen, 0, &cbc)) != CRYPT_OK) return err; - if ((err = cbc_encrypt(pt, ct, ptlen, &cbc)) != CRYPT_OK) - return err; - if ((err = cbc_done(&cbc)) != CRYPT_OK) - return err; - if ((err = unregister_cipher(&aes_desc)) != CRYPT_OK) + err= cbc_encrypt(pt, ct, tlen, &cbc); + (void)cbc_done(&cbc); + return err; +} + +static unsigned long tom_decrypt(void *key, int keylen, void *iv, + void *ct, void *pt, int tlen) +{ + symmetric_CBC cbc; + int index, err; + + if ((index = register_cipher(&aes_desc)) == -1) + return CRYPT_INVALID_CIPHER; + if ((err = cbc_start(index, iv, key, keylen, 0, &cbc)) != CRYPT_OK) return err; - return 0; + err= cbc_decrypt(ct, pt, tlen, &cbc); + (void)cbc_done(&cbc); + return err; } -static int tom_decrypt() +static unsigned long tom_hash(void *pt, int tlen, void *tag, int *taglen) { - return 0; + int index, rc; + unsigned long ltaglen = *taglen; + + if ((index = register_hash(&sha1_desc)) == -1) + return CRYPT_INVALID_HASH; + rc = hash_memory(index, pt, tlen, tag, <aglen); + *taglen = ltaglen; + return rc; } -static int tom_hash() +static unsigned long tom_hmac(void *key, int keylen, + void *pt, int tlen, void *tag, int *taglen) { - return 0; + int index, rc; + unsigned long ltaglen = *taglen; + + if (keylen != 20) return CRYPT_INVALID_KEYSIZE; + if ((index = register_hash(&sha1_desc)) == -1) + return CRYPT_INVALID_HASH; + rc = hmac_memory(index, key, keylen, pt, tlen, tag, <aglen); + *taglen = ltaglen; + return rc; } -static int tom_hmac() +static const char *tom_errstr(unsigned long err) { - return 0; + return error_to_string((int)err); } struct crypto_interface tom_crypto_if = { @@ -44,4 +69,5 @@ struct crypto_interface tom_crypto_if = { .decrypt = tom_decrypt, .hash = tom_hash, .hmac = tom_hmac, + .errstr = tom_errstr, }; diff --git a/ykneo.c b/ykneo.c index 68ef65e..2510e18 100644 --- a/ykneo.c +++ b/ykneo.c @@ -38,7 +38,7 @@ static DWORD ykn_check_atr_hb(BYTE *str, DWORD size) return SCARD_S_SUCCESS; } -static DWORD ykn_prologue(SCARDHANDLE hCard,LPTSTR envp[]) +static DWORD ykn_prologue(SCARDHANDLE hCard) { BYTE buf[258]; DWORD rsize = sizeof(buf); @@ -52,8 +52,8 @@ static DWORD ykn_prologue(SCARDHANDLE hCard,LPTSTR envp[]) else return SCARD_W_CARD_NOT_AUTHENTICATED; } -static DWORD ykn_trancieve(SCARDHANDLE hCard,LPTSTR envp[], - LPTSTR send, DWORD sendsize, BYTE *recv, LPDWORD recvsize_p) +static DWORD ykn_trancieve(SCARDHANDLE hCard, + BYTE *send, DWORD sendsize, BYTE *recv, LPDWORD recvsize_p) { DWORD rc; DWORD rsize = *recvsize_p + 2; @@ -74,7 +74,7 @@ static DWORD ykn_trancieve(SCARDHANDLE hCard,LPTSTR envp[], return SCARD_S_SUCCESS; } -static DWORD ykn_epilogue(SCARDHANDLE hCard,LPTSTR envp[]) +static DWORD ykn_epilogue(SCARDHANDLE hCard) { return SCardEndTransaction(hCard, SCARD_LEAVE_CARD); } -- 2.39.2