31
31
#include "sys-core.h"
32
32
#include "sys-rc4.h"
33
33
#include "sys-aes.h"
34
- #include "sys-dh.h"
35
34
#include "uECC.h"
36
35
#ifndef EXCLUDE_CHACHA20POLY1305
37
36
#include "sys-chacha20.h"
38
37
#include "sys-poly1305.h"
39
38
#endif
40
39
#include "mbedtls/rsa.h"
40
+ #include "mbedtls/dhm.h"
41
+ #include "mbedtls/bignum.h"
41
42
#include "mbedtls/sha256.h"
42
43
#include "mbedtls/entropy.h"
43
44
#include "mbedtls/ctr_drbg.h"
@@ -53,6 +54,12 @@ typedef struct {
53
54
} ECC_CTX ;
54
55
55
56
typedef mbedtls_rsa_context RSA_CTX ;
57
+ typedef mbedtls_dhm_context DHM_CTX ;
58
+
59
+ // these 2 functions were defined as static in dhm.c file, so are not in the header!
60
+ extern int dhm_check_range (const mbedtls_mpi * param , const mbedtls_mpi * P );
61
+ extern int dhm_random_below (mbedtls_mpi * R , const mbedtls_mpi * M ,
62
+ int (* f_rng )(void * , unsigned char * , size_t ), void * p_rng );
56
63
57
64
/***********************************************************************
58
65
**
@@ -71,6 +78,7 @@ typedef mbedtls_rsa_context RSA_CTX;
71
78
Register_Handle (SYM_AES , sizeof (AES_CTX ), NULL );
72
79
Register_Handle (SYM_ECDH , sizeof (ECC_CTX ), NULL );
73
80
Register_Handle (SYM_RC4 , sizeof (RC4_CTX ), NULL );
81
+ Register_Handle (SYM_DHM , sizeof (DHM_CTX ), (REB_HANDLE_FREE_FUNC )mbedtls_dhm_free );
74
82
Register_Handle (SYM_RSA , sizeof (RSA_CTX ), (REB_HANDLE_FREE_FUNC )mbedtls_rsa_free );
75
83
#ifndef EXCLUDE_CHACHA20POLY1305
76
84
Register_Handle (SYM_CHACHA20 , sizeof (poly1305_context ), NULL );
@@ -382,7 +390,7 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
382
390
383
391
//allocate new binary!
384
392
outBytes = mbedtls_rsa_get_len (rsa );
385
- data = Make_Binary (outBytes );
393
+ data = Make_Binary (outBytes - 1 );
386
394
outBinary = BIN_DATA (data );
387
395
388
396
if (refSign ) {
@@ -404,7 +412,7 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
404
412
405
413
return R_RET ;
406
414
error :
407
- //printf("err : -0x%0x\n", (unsigned int)-err);
415
+ //printf("RSA key init failed with error: : -0x%0x\n", (unsigned int)-err);
408
416
Free_Series (data );
409
417
return R_NONE ;
410
418
}
@@ -418,78 +426,58 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
418
426
// "Generates a new Diffie-Hellman private/public key pair"
419
427
// g [binary!] "Generator"
420
428
// p [binary!] "Field prime"
421
- // /into
422
- // dh-key [handle!] "Existing DH key handle"
423
429
// ]
424
430
***********************************************************************/
425
431
{
426
- REBSER * g = VAL_SERIES ( D_ARG (1 ) );
427
- REBSER * p = VAL_SERIES ( D_ARG (2 ) );
428
- REBOOL ref_into = D_REF (3 );
429
- REBVAL * val_dh = D_ARG (4 );
432
+ REBVAL * g = D_ARG (1 );
433
+ REBVAL * p = D_ARG (2 );
434
+ REBOOL ref_into = D_REF (3 );
435
+ REBVAL * val_dh = D_ARG (4 );
430
436
431
- DH_CTX * dh ;
432
- REBYTE * bin ;
433
- REBVAL * ret ;
437
+ REBINT err = 0 ;
438
+ DHM_CTX * dhm ;
434
439
435
- REBCNT len_g = BIN_LEN (g );
436
- REBCNT len_p = BIN_LEN (p );
437
- REBYTE * buffer = NULL ;
438
- REBSER * dh_ser ;
440
+ MAKE_HANDLE (D_RET , SYM_DHM );
441
+ dhm = (DHM_CTX * )VAL_HANDLE_CONTEXT_DATA (D_RET );
442
+ mbedtls_dhm_init (dhm );
439
443
440
- // allocating buffers for all keys as a one blob
441
- REBCNT buffer_len = BIN_LEN (g ) + (5 * BIN_LEN (p ));
442
-
443
- if (ref_into ) {
444
- if (!IS_HANDLE (val_dh ) || VAL_HANDLE_TYPE (val_dh ) != SYM_DH ) {
445
- //error!
446
- return R_NONE ;
447
- }
448
- ret = val_dh ;
449
- * D_RET = * D_ARG (4 );
450
- dh_ser = VAL_HANDLE_DATA (val_dh );
451
- if (dh_ser == NULL ) goto new_dh_handle ;
452
- HANDLE_CLR_FLAG (val_dh , HANDLE_RELEASABLE );
453
- if (SERIES_REST (dh_ser ) < (sizeof (DH_CTX ) + buffer_len )) {
454
- //needs more space for keys
455
- Expand_Series (dh_ser , AT_TAIL , (sizeof (DH_CTX ) + buffer_len ) - SERIES_TAIL (dh_ser ));
456
- }
457
- } else {
458
- ret = D_RET ;
459
- new_dh_handle :
460
- dh_ser = Make_Series (sizeof (DH_CTX ) + buffer_len , 1 , FALSE);
461
- SET_HANDLE (ret , dh_ser , SYM_DH , HANDLE_SERIES );
462
- }
463
- dh = (DH_CTX * )SERIES_DATA (dh_ser );
464
- buffer = SERIES_DATA (dh_ser ) + sizeof (DH_CTX );
465
- CLEAR (buffer , buffer_len );
466
- dh -> len_data = buffer_len ;
467
-
468
- bin = BIN_DATA (g ); //@@ use VAL_BIN_AT instead?
469
- dh -> len_g = len_g ;
470
- dh -> g = buffer ;
471
- COPY_MEM (dh -> g , bin , len_g );
472
-
473
- buffer += len_g ;
444
+ err = mbedtls_mpi_read_binary (& dhm -> MBEDTLS_PRIVATE (P ), VAL_BIN_AT (p ), VAL_SERIES (p )-> tail - VAL_INDEX (p ) );
445
+ if (err ) goto error ;
446
+ err = mbedtls_mpi_read_binary ( & dhm -> MBEDTLS_PRIVATE (G ), VAL_BIN_AT (g ), VAL_SERIES (g )-> tail - VAL_INDEX (g ));
447
+ if (err ) goto error ;
474
448
475
- bin = BIN_DATA (p );
476
- dh -> len = len_p ;
477
- dh -> p = buffer ;
478
- COPY_MEM (dh -> p , bin , len_p );
479
-
480
- buffer += len_p ;
481
-
482
- dh -> x = buffer ; //private key
483
- buffer += len_p ;
484
- dh -> gx = buffer ; //public key (self)
485
- buffer += len_p ;
486
- dh -> gy = buffer ; //public key (peer)
487
- buffer += len_p ;
488
- dh -> k = buffer ; //negotiated key
489
-
490
- DH_generate_key (dh );
449
+ size_t n = mbedtls_dhm_get_len (dhm );
450
+ if (n < 64 || n > 512 ) goto error ;
451
+
452
+ /* Generate private key X as large as possible ( <= P - 2 ) */
453
+ err = dhm_random_below (
454
+ & dhm -> MBEDTLS_PRIVATE (X ),
455
+ & dhm -> MBEDTLS_PRIVATE (P ),
456
+ mbedtls_ctr_drbg_random , & ctr_drbg );
457
+ if (err ) goto error ;
458
+
459
+ /*
460
+ * Calculate public key (self) GX = G^X mod P
461
+ */
462
+ err = mbedtls_mpi_exp_mod (
463
+ & dhm -> MBEDTLS_PRIVATE (GX ),
464
+ & dhm -> MBEDTLS_PRIVATE (G ),
465
+ & dhm -> MBEDTLS_PRIVATE (X ),
466
+ & dhm -> MBEDTLS_PRIVATE (P ),
467
+ & dhm -> MBEDTLS_PRIVATE (RP ));
468
+ if (err ) goto error ;
469
+
470
+ err = dhm_check_range (
471
+ & dhm -> MBEDTLS_PRIVATE (GX ),
472
+ & dhm -> MBEDTLS_PRIVATE (P ));
473
+ if (err ) goto error ;
491
474
492
475
return R_RET ;
476
+
477
+ error :
478
+ //printf("DHM key init failed with error: -0x%0x\n", (unsigned int)-err);
479
+ Free_Hob (VAL_HANDLE_CTX (D_RET ));
480
+ return R_NONE ;
493
481
}
494
482
495
483
/***********************************************************************
@@ -506,62 +494,54 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
506
494
// ]
507
495
***********************************************************************/
508
496
{
509
- REBVAL * val_dh = D_ARG (1 );
510
- REBOOL ref_release = D_REF (2 );
511
- REBOOL ref_public = D_REF (3 );
512
- REBOOL ref_secret = D_REF (4 );
513
- REBVAL * pub_key = D_ARG (5 );
514
-
515
- REBVAL * ret = D_RET ;
516
- REBSER * bin ;
517
- REBCNT len ;
518
-
519
- if (ref_public && ref_secret ) {
497
+ REBVAL * key = D_ARG (1 );
498
+ REBOOL refRelease = D_REF (2 );
499
+ REBOOL refPublic = D_REF (3 );
500
+ REBOOL refSecret = D_REF (4 );
501
+ REBVAL * gy = D_ARG (5 );
502
+
503
+ REBSER * out = NULL ;
504
+ REBINT err ;
505
+ DHM_CTX * dhm ;
506
+ size_t gx_len , gy_len , olen = 0 ;
507
+
508
+ if (refPublic && refSecret ) {
520
509
// only one can be used
521
510
Trap0 (RE_BAD_REFINES );
522
511
}
523
512
524
- if (VAL_HANDLE_TYPE (val_dh ) != SYM_DH || VAL_HANDLE_DATA (val_dh ) == NULL ) {
525
- Trap0 (RE_INVALID_HANDLE );
526
- }
513
+ if (NOT_VALID_CONTEXT_HANDLE (key , SYM_DHM ))
514
+ return R_NONE ; //or? Trap0(RE_INVALID_HANDLE);
527
515
528
- REBSER * dh_ser = VAL_HANDLE_DATA (val_dh );
529
- DH_CTX * dh = (DH_CTX * )SERIES_DATA (dh_ser );
530
-
531
- if (dh -> g == NULL ) return R_NONE ; //or error?
516
+ dhm = (DHM_CTX * )VAL_HANDLE_CONTEXT_DATA (key );
532
517
533
- if (ref_public ) {
534
- bin = Make_Binary (dh -> len );
535
- COPY_MEM (BIN_DATA (bin ), dh -> gx , dh -> len );
536
- SET_BINARY (ret , bin );
537
- BIN_LEN (bin ) = dh -> len ;
518
+ if (refPublic ) {
519
+ gx_len = mbedtls_mpi_size (& dhm -> MBEDTLS_PRIVATE (GX ));
520
+ if (gx_len <= 0 ) goto error ;
521
+ out = Make_Binary (gx_len - 1 );
522
+ mbedtls_mpi_write_binary (& dhm -> MBEDTLS_PRIVATE (GX ), BIN_DATA (out ), gx_len );
523
+ BIN_LEN (out ) = gx_len ;
538
524
}
539
-
540
- if (ref_secret ) {
541
- bin = VAL_SERIES (pub_key ); //@@ use VAL_BIN_AT instead?
542
- len = BIN_LEN (bin );
543
- if (len != dh -> len ) {
544
- return R_NONE ; // throw an error?
545
- }
546
- COPY_MEM (dh -> gy , BIN_DATA (bin ), len );
547
-
548
- DH_compute_key (dh );
549
-
550
- bin = Make_Binary (len );
551
- COPY_MEM (BIN_DATA (bin ), dh -> k , len );
552
- SET_BINARY (ret , bin );
553
- BIN_LEN (bin ) = len ;
525
+ if (refSecret ) {
526
+ // import oposite's side public data...
527
+ gy_len = VAL_SERIES (gy )-> tail - VAL_INDEX (gy );
528
+ err = mbedtls_mpi_read_binary (& dhm -> MBEDTLS_PRIVATE (GY ), VAL_BIN_AT (gy ), gy_len );
529
+ if (err ) goto error ;
530
+ out = Make_Binary (gy_len - 1 );
531
+ // and derive the shared secret of these 2 public parts
532
+ err = mbedtls_dhm_calc_secret (dhm , BIN_DATA (out ), gy_len , & olen , mbedtls_ctr_drbg_random , & ctr_drbg );
533
+ if (err ) goto error ;
534
+ BIN_LEN (out ) = olen ;
554
535
}
555
-
556
- if (ref_release ) {
557
- // if(dh->data != NULL) FREE_MEM(dh->data);
558
- CLEARS (dh );
559
- HANDLE_SET_FLAG (val_dh , HANDLE_RELEASABLE );
560
- if (!ref_public && !ref_secret ) return R_ARG1 ;
536
+ if (refRelease ) {
537
+ Free_Hob (VAL_HANDLE_CTX (key ));
538
+ if (!out ) return R_TRUE ;
561
539
}
562
-
540
+ SET_BINARY ( D_RET , out );
563
541
return R_RET ;
564
-
542
+ error :
543
+ if (out != NULL ) FREE_SERIES (out );
544
+ return R_NONE ;
565
545
}
566
546
567
547
0 commit comments