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