11#include "bqfc.h"
22
3- #include <assert.h>
43#include <limits.h>
54#include <stdlib.h>
65#include <string.h>
@@ -120,18 +119,25 @@ int bqfc_decompr(mpz_t out_a, mpz_t out_b, const mpz_t D, const struct qfb_c *c)
120119 return ret ;
121120}
122121
123- static void bqfc_export (uint8_t * out_str , size_t * offset , size_t size ,
122+ static int bqfc_export (uint8_t * out_str , size_t * offset , size_t size ,
124123 const mpz_t n )
125124{
126- size_t bytes ;
125+ size_t bytes = 0 ;
126+ const size_t bits = (size_t )mpz_sizeinbase (n , 2 );
127+ const size_t needed_bytes = (bits + 7 ) / 8 ;
128+
129+ if (needed_bytes > size ) {
130+ return -1 ;
131+ }
127132
128- // mpz_export can overflow out_str if reduction bug but this should never happen
129133 mpz_export (& out_str [* offset ], & bytes , -1 , 1 , 0 , 0 , n );
130- if (bytes > size )
131- gmp_printf ("bqfc_export overflow offset %d size %d n %Zd\n" , * offset , size , n );
134+ if (bytes > size ) {
135+ return -1 ;
136+ }
132137 if (bytes < size )
133138 memset (& out_str [* offset + bytes ], 0 , size - bytes );
134139 * offset += size ;
140+ return 0 ;
135141}
136142
137143enum BQFC_FLAG_BITS {
@@ -171,20 +177,29 @@ int bqfc_serialize_only(uint8_t *out_str, const struct qfb_c *c, size_t d_bits)
171177{
172178 size_t offset , g_size ;
173179
180+ if (d_bits == 0 || d_bits > BQFC_MAX_D_BITS )
181+ return -1 ;
174182 d_bits = (d_bits + 31 ) & ~(size_t )31 ;
183+ if (d_bits > BQFC_MAX_D_BITS )
184+ return -1 ;
175185
176186 out_str [0 ] = (uint8_t )c -> b_sign << BQFC_B_SIGN_BIT ;
177187 out_str [0 ] |= (mpz_sgn (c -> t ) < 0 ? 1 : 0 ) << BQFC_T_SIGN_BIT ;
178188 g_size = (mpz_sizeinbase (c -> g , 2 ) + 7 ) / 8 - 1 ;
179- assert (g_size <= UCHAR_MAX );
189+ if (g_size > UCHAR_MAX )
190+ return -1 ;
180191 out_str [1 ] = (uint8_t )g_size ;
181192 offset = 2 ;
182193
183- bqfc_export (out_str , & offset , d_bits / 16 - g_size , c -> a );
184- bqfc_export (out_str , & offset , d_bits / 32 - g_size , c -> t );
194+ if (bqfc_export (out_str , & offset , d_bits / 16 - g_size , c -> a ))
195+ return -1 ;
196+ if (bqfc_export (out_str , & offset , d_bits / 32 - g_size , c -> t ))
197+ return -1 ;
185198
186- bqfc_export (out_str , & offset , g_size + 1 , c -> g );
187- bqfc_export (out_str , & offset , g_size + 1 , c -> b0 );
199+ if (bqfc_export (out_str , & offset , g_size + 1 , c -> g ))
200+ return -1 ;
201+ if (bqfc_export (out_str , & offset , g_size + 1 , c -> b0 ))
202+ return -1 ;
188203
189204 return 0 ;
190205}
@@ -193,7 +208,11 @@ int bqfc_deserialize_only(struct qfb_c *out_c, const uint8_t *str, size_t d_bits
193208{
194209 size_t offset , bytes , g_size ;
195210
211+ if (d_bits == 0 || d_bits > BQFC_MAX_D_BITS )
212+ return -1 ;
196213 d_bits = (d_bits + 31 ) & ~(size_t )31 ;
214+ if (d_bits > BQFC_MAX_D_BITS )
215+ return -1 ;
197216
198217 g_size = str [1 ];
199218 if (g_size >= d_bits / 32 )
@@ -225,8 +244,11 @@ int bqfc_deserialize_only(struct qfb_c *out_c, const uint8_t *str, size_t d_bits
225244
226245int bqfc_get_compr_size (size_t d_bits )
227246{
247+ if (d_bits == 0 || d_bits > BQFC_MAX_D_BITS )
248+ return -1 ;
228249 size_t size = (d_bits + 31 ) / 32 * 3 + 4 ;
229- assert (size <= INT_MAX );
250+ if (size > INT_MAX )
251+ return -1 ;
230252 return (int )size ;
231253}
232254
@@ -235,6 +257,8 @@ int bqfc_serialize(uint8_t *out_str, mpz_t a, mpz_t b, size_t d_bits)
235257 struct qfb_c f_c ;
236258 int ret ;
237259 int valid_size = bqfc_get_compr_size (d_bits );
260+ if (valid_size <= 0 || valid_size > BQFC_FORM_SIZE )
261+ return -1 ;
238262
239263 if (!mpz_cmp_ui (b , 1 ) && mpz_cmp_ui (a , 2 ) <= 0 ) {
240264 out_str [0 ] = !mpz_cmp_ui (a , 2 ) ? BQFC_IS_GEN : BQFC_IS_1 ;
@@ -271,6 +295,8 @@ int bqfc_deserialize(mpz_t out_a, mpz_t out_b, const mpz_t D, const uint8_t *str
271295 struct qfb_c f_c ;
272296 int ret ;
273297
298+ if (d_bits == 0 || d_bits > BQFC_MAX_D_BITS )
299+ return -1 ;
274300 if (size != BQFC_FORM_SIZE )
275301 return -1 ;
276302
0 commit comments