Skip to content

Commit d6db6f5

Browse files
committed
CHANGE: replaced the old DH implementation with code from mbedTLS
1 parent e12f0ae commit d6db6f5

File tree

12 files changed

+1838
-125
lines changed

12 files changed

+1838
-125
lines changed
File renamed without changes.
File renamed without changes.

src/core/mbedtls/dhm.c

+748
Large diffs are not rendered by default.

src/core/n-crypt.c

+92-112
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@
3131
#include "sys-core.h"
3232
#include "sys-rc4.h"
3333
#include "sys-aes.h"
34-
#include "sys-dh.h"
3534
#include "uECC.h"
3635
#ifndef EXCLUDE_CHACHA20POLY1305
3736
#include "sys-chacha20.h"
3837
#include "sys-poly1305.h"
3938
#endif
4039
#include "mbedtls/rsa.h"
40+
#include "mbedtls/dhm.h"
41+
#include "mbedtls/bignum.h"
4142
#include "mbedtls/sha256.h"
4243
#include "mbedtls/entropy.h"
4344
#include "mbedtls/ctr_drbg.h"
@@ -53,6 +54,12 @@ typedef struct {
5354
} ECC_CTX;
5455

5556
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);
5663

5764
/***********************************************************************
5865
**
@@ -71,6 +78,7 @@ typedef mbedtls_rsa_context RSA_CTX;
7178
Register_Handle(SYM_AES, sizeof(AES_CTX), NULL);
7279
Register_Handle(SYM_ECDH, sizeof(ECC_CTX), NULL);
7380
Register_Handle(SYM_RC4, sizeof(RC4_CTX), NULL);
81+
Register_Handle(SYM_DHM, sizeof(DHM_CTX), (REB_HANDLE_FREE_FUNC)mbedtls_dhm_free);
7482
Register_Handle(SYM_RSA, sizeof(RSA_CTX), (REB_HANDLE_FREE_FUNC)mbedtls_rsa_free);
7583
#ifndef EXCLUDE_CHACHA20POLY1305
7684
Register_Handle(SYM_CHACHA20, sizeof(poly1305_context), NULL);
@@ -382,7 +390,7 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
382390

383391
//allocate new binary!
384392
outBytes = mbedtls_rsa_get_len(rsa);
385-
data = Make_Binary(outBytes);
393+
data = Make_Binary(outBytes-1);
386394
outBinary = BIN_DATA(data);
387395

388396
if (refSign) {
@@ -404,7 +412,7 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
404412

405413
return R_RET;
406414
error:
407-
//printf("err: -0x%0x\n", (unsigned int)-err);
415+
//printf("RSA key init failed with error:: -0x%0x\n", (unsigned int)-err);
408416
Free_Series(data);
409417
return R_NONE;
410418
}
@@ -418,78 +426,58 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
418426
// "Generates a new Diffie-Hellman private/public key pair"
419427
// g [binary!] "Generator"
420428
// p [binary!] "Field prime"
421-
// /into
422-
// dh-key [handle!] "Existing DH key handle"
423429
// ]
424430
***********************************************************************/
425431
{
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);
430436

431-
DH_CTX *dh;
432-
REBYTE *bin;
433-
REBVAL *ret;
437+
REBINT err = 0;
438+
DHM_CTX *dhm;
434439

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);
439443

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;
474448

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;
491474

492475
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;
493481
}
494482

495483
/***********************************************************************
@@ -506,62 +494,54 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
506494
// ]
507495
***********************************************************************/
508496
{
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) {
520509
// only one can be used
521510
Trap0(RE_BAD_REFINES);
522511
}
523512

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);
527515

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);
532517

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;
538524
}
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;
554535
}
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;
561539
}
562-
540+
SET_BINARY(D_RET, out);
563541
return R_RET;
564-
542+
error:
543+
if (out != NULL) FREE_SERIES(out);
544+
return R_NONE;
565545
}
566546

567547

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)