create test for crypto
[pam_pcsc_cr.git] / ossl_crypto.c
1 #include <openssl/err.h>
2 #include <openssl/sha.h>
3 #include <openssl/evp.h>
4 #include <openssl/hmac.h>
5
6 #include "crypto_if.h"
7
8 static unsigned long ossl_encrypt(void *key, int keylen, void *iv,
9                         void *pt, void *ct, int tlen)
10 {
11         EVP_CIPHER_CTX ctx;
12         int outlen1, outlen2;
13         unsigned char hkey[16];
14
15         if (EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(),
16                         NULL, key, keylen, 5, hkey, NULL) != 16) return 1UL;
17         if (!EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), hkey, iv))
18                 return ERR_get_error();
19         if (!EVP_EncryptUpdate(&ctx, ct, &outlen1, pt, tlen))
20                 return ERR_get_error();
21         if (!EVP_EncryptFinal(&ctx, ct + outlen1, &outlen2))
22                 return ERR_get_error();
23         if (outlen1 + outlen2 != tlen) return 1UL;
24         return 0UL;
25 }
26
27 static unsigned long ossl_decrypt(void *key, int keylen, void *iv,
28                         void *ct, void *pt, int tlen)
29 {
30         EVP_CIPHER_CTX ctx;
31         int outlen1, outlen2;
32         unsigned char hkey[16];
33
34         if (EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(),
35                         NULL, key, keylen, 5, hkey, NULL) != 16) return 1UL;
36         if (!EVP_DecryptInit(&ctx, EVP_aes_128_cbc(), hkey, iv))
37                 return ERR_get_error();
38         if (!EVP_DecryptUpdate(&ctx, ct, &outlen1, pt, tlen))
39                 return ERR_get_error();
40         if (!EVP_DecryptFinal(&ctx, ct + outlen1, &outlen2))
41                 return ERR_get_error();
42         if (outlen1 + outlen2 != tlen) return 1UL;
43         return 0UL;
44 }
45
46 static unsigned long ossl_hash(void *pt, int tlen, void *tag, int *taglen)
47 {
48         SHA_CTX sctx;
49
50         if (!SHA1_Init(&sctx)) return ERR_get_error();
51         if (!SHA1_Update(&sctx, pt, tlen)) return ERR_get_error();
52         if (!SHA1_Final(tag, &sctx)) return ERR_get_error();
53         *taglen = 160;
54         return 0UL;
55 }
56
57 static unsigned long ossl_hmac(void *pt, int tlen, void *key, int keylen,
58                         void *tag, int *taglen)
59 {
60         HMAC_CTX hctx;
61
62         HMAC_CTX_init(&hctx);
63         if (!HMAC_Init(&hctx, key, keylen, EVP_sha1())) return ERR_get_error();
64         if (!HMAC_Update(&hctx, pt, tlen)) return ERR_get_error();
65         if (!HMAC_Final(&hctx, tag, (unsigned int *)taglen))
66                 return ERR_get_error();
67         HMAC_CTX_cleanup(&hctx);
68         return 0UL;
69 }
70
71 static const char *ossl_errstr(unsigned long err)
72 {
73         return ERR_error_string(err, NULL);
74 }
75
76 struct crypto_interface ossl_crypto_if = {
77         .name           = "openssl",
78         .encrypt        = ossl_encrypt,
79         .decrypt        = ossl_decrypt,
80         .hash           = ossl_hash,
81         .hmac           = ossl_hmac,
82         .errstr         = ossl_errstr,
83 };