1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file pkcs_1_mgf1.c
7 The Mask Generation Function (MGF1) for PKCS #1, Tom St Denis
8 */
9
10 #ifdef LTC_PKCS_1
11
12 /**
13 Perform PKCS #1 MGF1 (internal)
14 @param hash_idx The index of the hash desired
15 @param seed The seed for MGF1
16 @param seedlen The length of the seed
17 @param mask [out] The destination
18 @param masklen The length of the mask desired
19 @return CRYPT_OK if successful
20 */
pkcs_1_mgf1(int hash_idx,const unsigned char * seed,unsigned long seedlen,unsigned char * mask,unsigned long masklen)21 int pkcs_1_mgf1(int hash_idx,
22 const unsigned char *seed, unsigned long seedlen,
23 unsigned char *mask, unsigned long masklen)
24 {
25 unsigned long hLen, x;
26 ulong32 counter;
27 int err;
28 hash_state *md;
29 unsigned char *buf;
30
31 LTC_ARGCHK(seed != NULL);
32 LTC_ARGCHK(mask != NULL);
33
34 /* ensure valid hash */
35 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
36 return err;
37 }
38
39 /* get hash output size */
40 hLen = hash_descriptor[hash_idx]->hashsize;
41
42 /* allocate memory */
43 md = XMALLOC(sizeof(hash_state));
44 buf = XMALLOC(hLen);
45 if (md == NULL || buf == NULL) {
46 if (md != NULL) {
47 XFREE(md);
48 }
49 if (buf != NULL) {
50 XFREE(buf);
51 }
52 return CRYPT_MEM;
53 }
54
55 /* start counter */
56 counter = 0;
57
58 while (masklen > 0) {
59 /* handle counter */
60 STORE32H(counter, buf);
61 ++counter;
62
63 /* get hash of seed || counter */
64 if ((err = hash_descriptor[hash_idx]->init(md)) != CRYPT_OK) {
65 goto LBL_ERR;
66 }
67 if ((err = hash_descriptor[hash_idx]->process(md, seed, seedlen)) != CRYPT_OK) {
68 goto LBL_ERR;
69 }
70 if ((err = hash_descriptor[hash_idx]->process(md, buf, 4)) != CRYPT_OK) {
71 goto LBL_ERR;
72 }
73 if ((err = hash_descriptor[hash_idx]->done(md, buf)) != CRYPT_OK) {
74 goto LBL_ERR;
75 }
76
77 /* store it */
78 for (x = 0; x < hLen && masklen > 0; x++, masklen--) {
79 *mask++ = buf[x];
80 }
81 }
82
83 err = CRYPT_OK;
84 LBL_ERR:
85 #ifdef LTC_CLEAN_STACK
86 zeromem(buf, hLen);
87 zeromem(md, sizeof(hash_state));
88 #endif
89
90 XFREE(buf);
91 XFREE(md);
92
93 return err;
94 }
95
96 #endif /* LTC_PKCS_1 */
97