@@ -183,9 +183,9 @@ PyInit__blake2(void)
183
183
typedef enum { Blake2s , Blake2b } blake2_alg ;
184
184
185
185
static inline blake2_alg type_to_alg (PyTypeObject * type ) {
186
- if (type -> tp_name == blake2b_type_spec .name )
186
+ if (! strcmp ( type -> tp_name , blake2b_type_spec .name ) )
187
187
return Blake2b ;
188
- else if (type -> tp_name == blake2s_type_spec .name )
188
+ else if (! strcmp ( type -> tp_name , blake2s_type_spec .name ) )
189
189
return Blake2s ;
190
190
else
191
191
Py_UNREACHABLE ();
@@ -207,8 +207,9 @@ typedef struct {
207
207
/*[clinic input]
208
208
module _blake2
209
209
class _blake2.blake2b "Blake2Object *" "&PyBlake2_BLAKE2bType"
210
+ class _blake2.blake2s "Blake2Object *" "&PyBlake2_BLAKE2sType"
210
211
[clinic start generated code]*/
211
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=0b180617d6a53dca ]*/
212
+ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b7526666bd18af83 ]*/
212
213
213
214
214
215
static Blake2Object *
@@ -270,35 +271,13 @@ static void update(Blake2Object *self, uint8_t *buf, Py_ssize_t len) {
270
271
}
271
272
}
272
273
273
- /*[clinic input]
274
- @classmethod
275
- _blake2.blake2b.__new__ as py_blake2b_new
276
- data: object(c_default="NULL") = b''
277
- /
278
- *
279
- digest_size: int(c_default="HACL_HASH_BLAKE2B_OUT_BYTES") = _blake2.blake2b.MAX_DIGEST_SIZE
280
- key: Py_buffer(c_default="NULL", py_default="b''") = None
281
- salt: Py_buffer(c_default="NULL", py_default="b''") = None
282
- person: Py_buffer(c_default="NULL", py_default="b''") = None
283
- fanout: int = 1
284
- depth: int = 1
285
- leaf_size: unsigned_long = 0
286
- node_offset: unsigned_long_long = 0
287
- node_depth: int = 0
288
- inner_size: int = 0
289
- last_node: bool = False
290
- usedforsecurity: bool = True
291
-
292
- Return a new BLAKE2b hash object.
293
- [clinic start generated code]*/
294
-
295
274
static PyObject *
296
- py_blake2b_new_impl (PyTypeObject * type , PyObject * data , int digest_size ,
275
+ py_blake2b_or_s_new (PyTypeObject * type , PyObject * data , int digest_size ,
297
276
Py_buffer * key , Py_buffer * salt , Py_buffer * person ,
298
277
int fanout , int depth , unsigned long leaf_size ,
299
278
unsigned long long node_offset , int node_depth ,
300
279
int inner_size , int last_node , int usedforsecurity )
301
- /*[clinic end generated code: output=32bfd8f043c6896f input=8fee2b7b11428b2d]*/
280
+
302
281
{
303
282
Blake2Object * self = NULL ;
304
283
Py_buffer buf ;
@@ -310,34 +289,40 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
310
289
311
290
self -> alg = type_to_alg (type );
312
291
292
+ // Using Blake2b because we statically know that these are greater than the
293
+ // Blake2s sizes -- this avoids a VLA.
313
294
uint8_t salt_ [HACL_HASH_BLAKE2B_SALT_BYTES ] = { 0 };
314
295
uint8_t personal_ [HACL_HASH_BLAKE2B_PERSONAL_BYTES ] = { 0 };
315
296
316
297
/* Validate digest size. */
317
- if (digest_size <= 0 || (unsigned ) digest_size > HACL_HASH_BLAKE2B_OUT_BYTES ) {
298
+ if (digest_size <= 0 ||
299
+ (unsigned ) digest_size > (self -> alg == Blake2b ? HACL_HASH_BLAKE2B_OUT_BYTES : HACL_HASH_BLAKE2S_OUT_BYTES ))
300
+ {
318
301
PyErr_Format (PyExc_ValueError ,
319
- "digest_size must be between 1 and %d bytes" ,
320
- HACL_HASH_BLAKE2B_OUT_BYTES );
302
+ "digest_size for %s must be between 1 and %d bytes, here it is %d" ,
303
+ self -> alg == Blake2b ? "Blake2b" : "Blake2s" ,
304
+ self -> alg == Blake2b ? HACL_HASH_BLAKE2B_OUT_BYTES : HACL_HASH_BLAKE2S_OUT_BYTES ,
305
+ digest_size );
321
306
goto error ;
322
307
}
323
308
324
309
/* Validate salt parameter. */
325
310
if ((salt -> obj != NULL ) && salt -> len ) {
326
- if (salt -> len > HACL_HASH_BLAKE2B_SALT_BYTES ) {
311
+ if (salt -> len > ( self -> alg == Blake2b ? HACL_HASH_BLAKE2B_SALT_BYTES : HACL_HASH_BLAKE2S_SALT_BYTES ) ) {
327
312
PyErr_Format (PyExc_ValueError ,
328
313
"maximum salt length is %d bytes" ,
329
- HACL_HASH_BLAKE2B_SALT_BYTES );
314
+ ( self -> alg == Blake2b ? HACL_HASH_BLAKE2B_SALT_BYTES : HACL_HASH_BLAKE2S_SALT_BYTES ) );
330
315
goto error ;
331
316
}
332
317
memcpy (salt_ , salt -> buf , salt -> len );
333
318
}
334
319
335
320
/* Validate personalization parameter. */
336
321
if ((person -> obj != NULL ) && person -> len ) {
337
- if (person -> len > HACL_HASH_BLAKE2B_PERSONAL_BYTES ) {
322
+ if (person -> len > ( self -> alg == Blake2b ? HACL_HASH_BLAKE2B_PERSONAL_BYTES : HACL_HASH_BLAKE2S_PERSONAL_BYTES ) ) {
338
323
PyErr_Format (PyExc_ValueError ,
339
324
"maximum person length is %d bytes" ,
340
- HACL_HASH_BLAKE2B_PERSONAL_BYTES );
325
+ ( self -> alg == Blake2b ? HACL_HASH_BLAKE2B_PERSONAL_BYTES : HACL_HASH_BLAKE2S_PERSONAL_BYTES ) );
341
326
goto error ;
342
327
}
343
328
memcpy (personal_ , person -> buf , person -> len );
@@ -373,19 +358,20 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
373
358
goto error ;
374
359
}
375
360
376
- if (inner_size < 0 || (unsigned ) inner_size > HACL_HASH_BLAKE2B_OUT_BYTES ) {
361
+ if (inner_size < 0 ||
362
+ (unsigned ) inner_size > (self -> alg == Blake2b ? HACL_HASH_BLAKE2B_OUT_BYTES : HACL_HASH_BLAKE2S_OUT_BYTES )) {
377
363
PyErr_Format (PyExc_ValueError ,
378
364
"inner_size must be between 0 and is %d" ,
379
- HACL_HASH_BLAKE2B_OUT_BYTES );
365
+ ( self -> alg == Blake2b ? HACL_HASH_BLAKE2B_OUT_BYTES : HACL_HASH_BLAKE2S_OUT_BYTES ) );
380
366
goto error ;
381
367
}
382
368
383
369
/* Set key length. */
384
370
if ((key -> obj != NULL ) && key -> len ) {
385
- if (key -> len > HACL_HASH_BLAKE2B_KEY_BYTES ) {
371
+ if (key -> len > ( self -> alg == Blake2b ? HACL_HASH_BLAKE2B_KEY_BYTES : HACL_HASH_BLAKE2S_KEY_BYTES ) ) {
386
372
PyErr_Format (PyExc_ValueError ,
387
373
"maximum key length is %d bytes" ,
388
- HACL_HASH_BLAKE2B_KEY_BYTES );
374
+ ( self -> alg == Blake2b ? HACL_HASH_BLAKE2B_KEY_BYTES : HACL_HASH_BLAKE2S_KEY_BYTES ) );
389
375
goto error ;
390
376
}
391
377
}
@@ -440,6 +426,72 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
440
426
return NULL ;
441
427
}
442
428
429
+ /*[clinic input]
430
+ @classmethod
431
+ _blake2.blake2b.__new__ as py_blake2b_new
432
+ data: object(c_default="NULL") = b''
433
+ /
434
+ *
435
+ digest_size: int(c_default="HACL_HASH_BLAKE2B_OUT_BYTES") = _blake2.blake2b.MAX_DIGEST_SIZE
436
+ key: Py_buffer(c_default="NULL", py_default="b''") = None
437
+ salt: Py_buffer(c_default="NULL", py_default="b''") = None
438
+ person: Py_buffer(c_default="NULL", py_default="b''") = None
439
+ fanout: int = 1
440
+ depth: int = 1
441
+ leaf_size: unsigned_long = 0
442
+ node_offset: unsigned_long_long = 0
443
+ node_depth: int = 0
444
+ inner_size: int = 0
445
+ last_node: bool = False
446
+ usedforsecurity: bool = True
447
+
448
+ Return a new BLAKE2b hash object.
449
+ [clinic start generated code]*/
450
+
451
+ static PyObject *
452
+ py_blake2b_new_impl (PyTypeObject * type , PyObject * data , int digest_size ,
453
+ Py_buffer * key , Py_buffer * salt , Py_buffer * person ,
454
+ int fanout , int depth , unsigned long leaf_size ,
455
+ unsigned long long node_offset , int node_depth ,
456
+ int inner_size , int last_node , int usedforsecurity )
457
+ /*[clinic end generated code: output=32bfd8f043c6896f input=8fee2b7b11428b2d]*/
458
+ {
459
+ return py_blake2b_or_s_new (type , data , digest_size , key , salt , person , fanout , depth , leaf_size , node_offset , node_depth , inner_size , last_node , usedforsecurity );
460
+ }
461
+
462
+ /*[clinic input]
463
+ @classmethod
464
+ _blake2.blake2s.__new__ as py_blake2s_new
465
+ data: object(c_default="NULL") = b''
466
+ /
467
+ *
468
+ digest_size: int(c_default="HACL_HASH_BLAKE2S_OUT_BYTES") = _blake2.blake2s.MAX_DIGEST_SIZE
469
+ key: Py_buffer(c_default="NULL", py_default="b''") = None
470
+ salt: Py_buffer(c_default="NULL", py_default="b''") = None
471
+ person: Py_buffer(c_default="NULL", py_default="b''") = None
472
+ fanout: int = 1
473
+ depth: int = 1
474
+ leaf_size: unsigned_long = 0
475
+ node_offset: unsigned_long_long = 0
476
+ node_depth: int = 0
477
+ inner_size: int = 0
478
+ last_node: bool = False
479
+ usedforsecurity: bool = True
480
+
481
+ Return a new BLAKE2s hash object.
482
+ [clinic start generated code]*/
483
+
484
+ static PyObject *
485
+ py_blake2s_new_impl (PyTypeObject * type , PyObject * data , int digest_size ,
486
+ Py_buffer * key , Py_buffer * salt , Py_buffer * person ,
487
+ int fanout , int depth , unsigned long leaf_size ,
488
+ unsigned long long node_offset , int node_depth ,
489
+ int inner_size , int last_node , int usedforsecurity )
490
+ /*[clinic end generated code: output=556181f73905c686 input=8165a11980eac7f3]*/
491
+ {
492
+ return py_blake2b_or_s_new (type , data , digest_size , key , salt , person , fanout , depth , leaf_size , node_offset , node_depth , inner_size , last_node , usedforsecurity );
493
+ }
494
+
443
495
/*[clinic input]
444
496
_blake2.blake2b.copy
445
497
@@ -575,15 +627,15 @@ static PyMethodDef py_blake2b_methods[] = {
575
627
static PyObject *
576
628
py_blake2b_get_name (Blake2Object * self , void * closure )
577
629
{
578
- return PyUnicode_FromString ("blake2b" );
630
+ return PyUnicode_FromString (self -> alg == Blake2b ? "blake2b" : "blake2s " );
579
631
}
580
632
581
633
582
634
583
635
static PyObject *
584
636
py_blake2b_get_block_size (Blake2Object * self , void * closure )
585
637
{
586
- return PyLong_FromLong (HACL_HASH_BLAKE2B_BLOCK_BYTES );
638
+ return PyLong_FromLong (self -> alg == Blake2b ? HACL_HASH_BLAKE2B_BLOCK_BYTES : HACL_HASH_BLAKE2S_BLOCK_BYTES );
587
639
}
588
640
589
641
@@ -618,9 +670,17 @@ py_blake2b_dealloc(Blake2Object *self)
618
670
{
619
671
switch (self -> alg ) {
620
672
case Blake2b :
621
- Hacl_Hash_Blake2b_free (self -> blake2b_state );
673
+ // This happens if we hit "goto error" in the middle of the
674
+ // initialization function. We leverage the fact that tp_alloc
675
+ // guarantees that the contents of the object are NULL-initialized
676
+ // (see documentation for PyType_GenericAlloc) to detect this case.
677
+ if (self -> blake2b_state != NULL )
678
+ Hacl_Hash_Blake2b_free (self -> blake2b_state );
679
+ break ;
622
680
case Blake2s :
623
- Hacl_Hash_Blake2s_free (self -> blake2s_state );
681
+ if (self -> blake2b_state != NULL )
682
+ Hacl_Hash_Blake2s_free (self -> blake2s_state );
683
+ break ;
624
684
default :
625
685
Py_UNREACHABLE ();
626
686
}
@@ -630,7 +690,7 @@ py_blake2b_dealloc(Blake2Object *self)
630
690
Py_DECREF (type );
631
691
}
632
692
633
- static PyType_Slot blake2bs_type_slots [] = {
693
+ static PyType_Slot blake2b_type_slots [] = {
634
694
{Py_tp_dealloc , py_blake2b_dealloc },
635
695
{Py_tp_doc , (char * )py_blake2b_new__doc__ },
636
696
{Py_tp_methods , py_blake2b_methods },
@@ -639,16 +699,27 @@ static PyType_Slot blake2bs_type_slots[] = {
639
699
{0 ,0 }
640
700
};
641
701
702
+ static PyType_Slot blake2s_type_slots [] = {
703
+ {Py_tp_dealloc , py_blake2b_dealloc },
704
+ {Py_tp_doc , (char * )py_blake2s_new__doc__ },
705
+ {Py_tp_methods , py_blake2b_methods },
706
+ {Py_tp_getset , py_blake2b_getsetters },
707
+ // only the constructor differs, so that it can receive a clinic-generated
708
+ // default digest length suitable for blake2s
709
+ {Py_tp_new , py_blake2s_new },
710
+ {0 ,0 }
711
+ };
712
+
642
713
static PyType_Spec blake2b_type_spec = {
643
714
.name = "_blake2.blake2b" ,
644
715
.basicsize = sizeof (Blake2Object ),
645
716
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE ,
646
- .slots = blake2bs_type_slots
717
+ .slots = blake2b_type_slots
647
718
};
648
719
649
720
static PyType_Spec blake2s_type_spec = {
650
721
.name = "_blake2.blake2s" ,
651
722
.basicsize = sizeof (Blake2Object ),
652
723
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE ,
653
- .slots = blake2bs_type_slots
724
+ .slots = blake2s_type_slots
654
725
};
0 commit comments