22
23
#include "clamav-config.h"
26
29
#include <string.h>
27
30
#include <stdlib.h>
30
34
#include "clamav.h"
31
35
#include "others.h"
35
38
#include "sha256.h"
37
40
#define CLI_NSTR "118640995551645342603070001658453189751527774412027743746599405743243142607464144767361060640655844749760788890022283424922762488917565551002467771109669598189410434699034532232228621591089508178591428456220796841621637175567590476666928698770143328137383952820383197532047771780196576957695822641224262693037"
39
42
#define CLI_ESTR "100001027"
41
static char cli_ndecode(unsigned char value)
44
#define CLI_NSTRPSS "14783905874077467090262228516557917570254599638376203532031989214105552847269687489771975792123442185817287694951949800908791527542017115600501303394778618535864845235700041590056318230102449612217458549016089313306591388590790796515819654102320725712300822356348724011232654837503241736177907784198700834440681124727060540035754699658105895050096576226753008596881698828185652424901921668758326578462003247906470982092298106789657211905488986281078346361469524484829559560886227198091995498440676639639830463593211386055065360288422394053998134458623712540683294034953818412458362198117811990006021989844180721010947"
46
#define CLI_ESTRPSS "100002053"
48
#define PSS_NBITS 2048
49
#define PSS_DIGEST_LENGTH 32
52
static char cli_ndecode(char value)
45
56
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
46
57
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
64
static unsigned char *cli_decodesig(const char *sig, unsigned int plen, mp_int e, mp_int n)
75
static unsigned char *cli_decodesig(const char *sig, int plainlen, mpz_t e, mpz_t n)
66
int i, slen = strlen(sig), dec;
73
for(i = 0; i < slen; i++) {
77
int i, siglen = strlen(sig), dec;
78
unsigned char *decoded;
85
for(i = 0; i < siglen; i++) {
74
86
if((dec = cli_ndecode(sig[i])) < 0) {
80
mp_mul_2d(&r, 6 * i, &r);
93
mpz_mul_2exp(r, r, 6 * i);
84
plain = (unsigned char *) cli_calloc(plen + 1, sizeof(unsigned char));
86
cli_errmsg("cli_decodesig: Can't allocate memory for 'plain'\n");
97
decoded = (unsigned char *) cli_calloc(plainlen + 1, sizeof(unsigned char));
99
cli_errmsg("cli_decodesig: Can't allocate memory\n");
92
mp_exptmod(&c, &e, &n, &p); /* plain = cipher^e mod n */
95
for(i = plen - 1; i >= 0; i--) { /* reverse */
96
mp_div(&p, &c, &p, &r);
97
plain[i] = mp_get_int(&r);
106
mpz_powm(p, c, e, n); /* plain = cipher^e mod n */
109
for(i = plainlen - 1; i >= 0; i--) { /* reverse */
110
mpz_tdiv_qr_ui(p, r, p, 256);
111
decoded[i] = mpz_get_ui(r);
119
static void cli_mgf(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int outlen)
122
unsigned int i, laps;
123
unsigned char cnt[4], digest[PSS_DIGEST_LENGTH];
126
laps = (outlen + PSS_DIGEST_LENGTH - 1) / PSS_DIGEST_LENGTH;
128
for(i = 0; i < laps; i++) {
129
cnt[0] = (unsigned char) 0;
130
cnt[1] = (unsigned char) 0;
131
cnt[2] = (unsigned char) (i / 256);
132
cnt[3] = (unsigned char) i;
135
sha256_update(&ctx, in, inlen);
136
sha256_update(&ctx, cnt, sizeof(cnt));
138
sha256_digest(&ctx, digest);
141
memcpy(&out[i * PSS_DIGEST_LENGTH], digest, PSS_DIGEST_LENGTH);
143
memcpy(&out[i * PSS_DIGEST_LENGTH], digest, outlen - i * PSS_DIGEST_LENGTH);
147
int cli_versigpss(const unsigned char *sha256, const char *dsig)
151
unsigned char *pt, digest1[PSS_DIGEST_LENGTH], digest2[PSS_DIGEST_LENGTH], *salt;
152
unsigned int plen = PSS_NBITS / 8, hlen, slen, i;
153
unsigned char dblock[PSS_NBITS / 8 - PSS_DIGEST_LENGTH - 1];
154
unsigned char mblock[PSS_NBITS / 8 - PSS_DIGEST_LENGTH - 1];
155
unsigned char fblock[8 + 2 * PSS_DIGEST_LENGTH];
158
hlen = slen = PSS_DIGEST_LENGTH;
159
mpz_init_set_str(n, CLI_NSTRPSS, 10);
160
mpz_init_set_str(e, CLI_ESTRPSS, 10);
162
if(!(pt = cli_decodesig(dsig, plen, e, n))) {
171
if(pt[plen - 1] != 0xbc) {
172
cli_dbgmsg("cli_versigpss: Incorrect signature syntax (0xbc)\n");
177
memcpy(mblock, pt, plen - hlen - 1);
178
memcpy(digest2, &pt[plen - hlen - 1], hlen);
181
cli_mgf(digest2, hlen, dblock, plen - hlen - 1);
183
for(i = 0; i < plen - hlen - 1; i++)
184
dblock[i] ^= mblock[i];
186
dblock[0] &= (0xff >> 1);
188
salt = memchr(dblock, 0x01, sizeof(dblock));
190
cli_dbgmsg("cli_versigpss: Can't find salt\n");
195
if((unsigned int) (dblock + sizeof(dblock) - salt) != slen) {
196
cli_dbgmsg("cli_versigpss: Bad salt size\n");
200
memset(fblock, 0, 8);
201
memcpy(&fblock[8], sha256, hlen);
202
memcpy(&fblock[8 + hlen], salt, slen);
205
sha256_update(&ctx, fblock, sizeof(fblock));
207
sha256_digest(&ctx, digest1);
209
if(memcmp(digest1, digest2, hlen)) {
210
cli_dbgmsg("cli_versigpss: Signature doesn't match.\n");
214
cli_dbgmsg("cli_versigpss: Digital signature is correct.\n");
106
218
int cli_versig(const char *md5, const char *dsig)
112
224
if(strlen(md5) != 32 || !isalnum(md5[0])) {
113
225
/* someone is trying to fool us with empty/malformed MD5 ? */
114
226
cli_errmsg("SECURITY WARNING: MD5 basic test failure.\n");
119
mp_read_radix(&n, CLI_NSTR, 10);
121
mp_read_radix(&e, CLI_ESTR, 10);
230
mpz_init_set_str(n, CLI_NSTR, 10);
231
mpz_init_set_str(e, CLI_ESTR, 10);
123
233
if(!(pt = (char *) cli_decodesig(dsig, 16, e, n))) {
129
239
pt2 = cli_str2hex(pt, 16);
134
244
if(strncmp(md5, pt2, 32)) {
135
245
cli_dbgmsg("cli_versig: Signature doesn't match.\n");
146
256
cli_dbgmsg("cli_versig: Digital signature is correct.\n");
147
257
return CL_SUCCESS;
152
#define PAD_LEN (2048 / 8)
153
#define BLK_LEN (PAD_LEN - HASH_LEN - 1)
154
int cli_versig2(const unsigned char *sha256, const char *dsig_str, const char *n_str, const char *e_str)
156
unsigned char *decoded, digest1[HASH_LEN], digest2[HASH_LEN], digest3[HASH_LEN], *salt;
157
unsigned char mask[BLK_LEN], data[BLK_LEN], final[8 + 2 * HASH_LEN], c[4];
158
unsigned int i, rounds;
163
mp_read_radix(&e, e_str, 10);
165
mp_read_radix(&n, n_str, 10);
167
decoded = cli_decodesig(dsig_str, PAD_LEN, e, n);
173
if(decoded[PAD_LEN - 1] != 0xbc) {
178
memcpy(mask, decoded, BLK_LEN);
179
memcpy(digest2, &decoded[BLK_LEN], HASH_LEN);
183
rounds = (BLK_LEN + HASH_LEN - 1) / HASH_LEN;
184
for(i = 0; i < rounds; i++) {
185
c[2] = (unsigned char) (i / 256);
186
c[3] = (unsigned char) i;
188
sha256_update(&ctx, digest2, HASH_LEN);
189
sha256_update(&ctx, c, 4);
190
sha256_final(&ctx, digest3);
192
memcpy(&data[i * 32], digest3, BLK_LEN - i * HASH_LEN);
194
memcpy(&data[i * 32], digest3, HASH_LEN);
197
for(i = 0; i < BLK_LEN; i++)
199
data[0] &= (0xff >> 1);
201
if(!(salt = memchr(data, 0x01, BLK_LEN)))
205
if(data + BLK_LEN - salt != SALT_LEN)
209
memcpy(&final[8], sha256, HASH_LEN);
210
memcpy(&final[8 + HASH_LEN], salt, SALT_LEN);
213
sha256_update(&ctx, final, sizeof(final));
214
sha256_final(&ctx, digest1);
216
return memcmp(digest1, digest2, HASH_LEN) ? CL_EVERIFY : CL_SUCCESS;