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