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