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