forked from xianrenqiu/gmssl_engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcipher.c
executable file
·133 lines (117 loc) · 3.29 KB
/
cipher.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <stdio.h>
#include <stdlib.h>
#include "engine.h"
#include "cipher.h"
typedef struct cipher_ctx_ {
int nid;
EVP_CIPHER *cipher;
} cipher_info_t;
static int ciphers_nids[] =
{
NID_aes_128_ecb,
NID_aes_128_cbc,
NID_aes_128_ctr,
NID_aes_192_ecb,
NID_aes_192_cbc,
NID_aes_192_ctr,
NID_aes_256_ecb,
NID_aes_256_cbc,
NID_aes_256_ctr,
NID_aes_128_gcm,
NID_aes_256_gcm,
NID_sms4_ecb,
NID_sms4_cbc,
NID_sms4_ctr
};
static cipher_info_t info[] = {
// aes
{NID_aes_128_ecb, NULL},
{NID_aes_128_cbc, NULL},
{NID_aes_128_ctr, NULL},
{NID_aes_192_ecb, NULL},
{NID_aes_192_cbc, NULL},
{NID_aes_192_ctr, NULL},
{NID_aes_256_ecb, NULL},
{NID_aes_256_cbc, NULL},
{NID_aes_256_ctr, NULL},
{NID_aes_128_gcm, NULL},
{NID_aes_256_gcm, NULL},
// sm4
{NID_sms4_ecb, NULL},
{NID_sms4_cbc, NULL},
{NID_sms4_ctr, NULL},
};
static const EVP_CIPHER *gmssl_engine_cipher_sw_impl(int nid)
{
switch (nid) {
case NID_aes_128_ecb:
return EVP_aes_128_ecb();
case NID_aes_128_cbc:
return EVP_aes_128_cbc();
case NID_aes_128_ctr:
return EVP_aes_128_ctr();
case NID_aes_192_ecb:
return EVP_aes_192_ecb();
case NID_aes_192_cbc:
return EVP_aes_192_cbc();
case NID_aes_192_ctr:
return EVP_aes_192_ctr();
case NID_aes_256_ecb:
return EVP_aes_256_ecb();
case NID_aes_256_cbc:
return EVP_aes_256_cbc();
case NID_aes_256_ctr:
return EVP_aes_256_ctr();
case NID_aes_128_gcm:
return EVP_aes_128_gcm();
case NID_aes_256_gcm:
return EVP_aes_256_gcm();
case NID_sms4_ecb:
return EVP_sms4_ecb();
case NID_sms4_cbc:
return EVP_sms4_cbc();
case NID_sms4_ctr:
return EVP_sms4_ctr();
default:
printf("Invalid nid %d\n", nid);
return NULL;
}
}
#define GET_SW_CIPHER(ctx) \
gmssl_engine_cipher_sw_impl(EVP_CIPHER_CTX_nid((ctx)))
static int gmssl_engine_ciphers_do_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t len)
{
return EVP_CIPHER_meth_get_do_cipher(GET_SW_CIPHER(ctx))(ctx, out, in, len);
}
static const EVP_CIPHER *gmssl_engine_get_cipher(int nid)
{
for (int i = 0; i < sizeof(info)/sizeof(cipher_info_t); i++)
if (info[i].nid == nid)
return info[i].cipher;
return NULL;
}
int gmssl_engine_create_ciphers(void)
{
for (int i = 0; i < sizeof(info)/sizeof(cipher_info_t); i++)
{
EVP_CIPHER *temp = gmssl_engine_cipher_sw_impl(info[i].nid);
info[i].cipher = EVP_CIPHER_meth_dup(temp);
if (!EVP_CIPHER_meth_set_do_cipher(info[i].cipher, gmssl_engine_ciphers_do_cipher))
{
info[i].cipher = NULL;
EVP_CIPHER_meth_free(info[i].cipher);
return 0;
}
}
return 1;
}
int gmssl_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
{
if (!cipher)
{
*nids = ciphers_nids;
return (sizeof(ciphers_nids) / sizeof(ciphers_nids[0]));
}
*cipher = gmssl_engine_get_cipher(nid);
return (*cipher != NULL);
}