-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpkcs12.c
81 lines (62 loc) · 1.76 KB
/
pkcs12.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
#define BEECRYPT_DLL_EXPORT
#include "beecrypt/pkcs12.h"
int pkcs12_derive_key(const hashFunction* h, byte id, const byte* pdata, size_t psize, const byte* sdata, size_t ssize, size_t iterationcount, byte* ndata, size_t nsize)
{
int rc = -1;
size_t i, remain;
hashFunctionContext ctxt;
byte *digest;
digest = (byte*) malloc(h->digestsize);
if (!digest)
goto cleanup;
if (hashFunctionContextInit(&ctxt, h))
goto cleanup;
/* we start by hashing the diversifier; don't allocate a buffer for this */
for (i = 0; i < h->blocksize; i++)
hashFunctionContextUpdate(&ctxt, &id, 1);
/* next we hash the salt data, concatenating until we have a whole number of blocks */
if (ssize)
{
remain = ((ssize / h->blocksize) + (ssize % h->blocksize)) * h->blocksize;
while (remain > 0)
{
size_t tmp = remain > ssize ? ssize : remain;
hashFunctionContextUpdate(&ctxt, sdata, tmp);
remain -= tmp;
}
}
/* next we hash the password data, concatenating until we have a whole number of blocks */
if (psize)
{
remain = ((psize / h->blocksize) + (psize % h->blocksize)) * h->blocksize;
while (remain > 0)
{
size_t tmp = remain > psize ? psize : remain;
hashFunctionContextUpdate(&ctxt, pdata, tmp);
remain -= tmp;
}
}
/* now we iterate through the following loop */
while (iterationcount-- > 0)
{
hashFunctionContextDigest(&ctxt, digest);
hashFunctionContextUpdate(&ctxt, digest, h->digestsize);
}
/* do the final digest */
hashFunctionContextDigest(&ctxt, digest);
/* fill key */
while (nsize > 0)
{
size_t tmp = nsize > h->digestsize ? h->digestsize : nsize;
memcpy(ndata, digest, tmp);
ndata += tmp;
nsize -= tmp;
}
if (hashFunctionContextFree(&ctxt))
goto cleanup;
rc = 0;
cleanup:
if (digest)
free(digest);
return rc;
}