Streamlined DRBG and MGF1 debug output
[strongswan.git] / src / libstrongswan / plugins / ntru / ntru_crypto / ntru_crypto_ntru_mgftp1.c
1 /******************************************************************************
2 * NTRU Cryptography Reference Source Code
3 * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
4 *
5 * ntru_crypto_ntru_mgftp1.c is a component of ntru-crypto.
6 *
7 * Copyright (C) 2009-2013 Security Innovation
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 *
23 *****************************************************************************/
24
25 /******************************************************************************
26 *
27 * File: ntru_crypto_ntru_mgftp1.c
28 *
29 * Contents: Routines implementing MGF-TP-1.
30 *
31 *****************************************************************************/
32
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include "ntru_crypto_ntru_mgftp1.h"
37 #include "ntru_crypto_ntru_convert.h"
38
39 #include "ntru_mgf1.h"
40
41 /* ntru_mgftp1
42 *
43 * Implements a mask-generation function for trinary polynomials,
44 * MGF-TP-1, generating an arbitrary number of octets based on hashing
45 * a digest-length string concatenated with a 4-octet counter. From
46 * these octets, N trits are derived.
47 *
48 * The state (string and counter) is initialized when a seed is present.
49 *
50 * Returns NTRU_OK if successful.
51 * Returns NTRU_MGF1_FAIL if the MGF1 mask generator function fails
52 *
53 */
54
55 uint32_t
56 ntru_mgftp1(
57 hash_algorithm_t hash_algid, /* in - hash alg ID for
58 MGF-TP-1 */
59 uint8_t min_calls, /* in - minimum no. of hash
60 calls */
61 uint16_t seed_len, /* in - no. of octets in seed */
62 uint8_t *seed, /* in - pointer to seed */
63 uint8_t *buf, /* in - pointer to working
64 buffer */
65 uint16_t num_trits_needed, /* in - no. of trits in mask */
66 uint8_t *mask) /* out - address for mask trits */
67 {
68 uint8_t md_len;
69 uint8_t *octets;
70 uint16_t octets_available;
71 ntru_mgf1_t *mgf1;
72
73 /* generate minimum MGF1 output */
74 DBG2(DBG_LIB, "MGF1 is seeded with %u octets", seed_len);
75 mgf1 = ntru_mgf1_create(hash_algid, chunk_create(seed, seed_len), TRUE);
76 if (!mgf1)
77 {
78 return NTRU_MGF1_FAIL;
79 }
80 md_len = mgf1->get_hash_size(mgf1);
81 octets = buf;
82 octets_available = min_calls * md_len;
83
84 DBG2(DBG_LIB, "MGF1 generates %u octets to extract %d trits",
85 octets_available, num_trits_needed);
86 if (!mgf1->get_mask(mgf1, octets_available, octets))
87 {
88 mgf1->destroy(mgf1);
89 return NTRU_MGF1_FAIL;
90 }
91
92 /* get trits for mask */
93 while (num_trits_needed >= 5)
94 {
95 /* get another octet and convert it to 5 trits */
96 if (octets_available == 0)
97 {
98 octets = buf;
99 octets_available = md_len;
100
101 DBG2(DBG_LIB, "MGF1 generates another %u octets for the remaining "
102 "%u trits", octets_available, num_trits_needed);
103 if (!mgf1->get_mask(mgf1, octets_available, octets))
104 {
105 mgf1->destroy(mgf1);
106 return NTRU_MGF1_FAIL;
107 }
108 }
109
110 if (*octets < 243)
111 {
112 ntru_octet_2_trits(*octets, mask);
113 mask += 5;
114 num_trits_needed -= 5;
115 }
116 octets++;
117 --octets_available;
118 }
119
120 /* get any remaining trits */
121 while (num_trits_needed)
122 {
123 uint8_t trits[5];
124
125 /* get another octet and convert it to remaining trits */
126 if (octets_available == 0)
127 {
128 octets = buf;
129 octets_available = md_len;
130
131 DBG2(DBG_LIB, "MGF1 generates another %u octets for the remaining "
132 "%u trits", octets_available, num_trits_needed);
133 if (!mgf1->get_mask(mgf1, octets_available, octets))
134 {
135 mgf1->destroy(mgf1);
136 return NTRU_MGF1_FAIL;
137 }
138 }
139 if (*octets < 243)
140 {
141 ntru_octet_2_trits(*octets, trits);
142 memcpy(mask, trits, num_trits_needed);
143 num_trits_needed = 0;
144 }
145 else
146 {
147 octets++;
148 --octets_available;
149 }
150 }
151 mgf1->destroy(mgf1);
152
153 return NTRU_OK;
154 }
155
156