@@ -159,6 +159,16 @@ ZEND_BEGIN_ARG_INFO_EX(AI_MaybeKeyAndLength, 0, 0, 0)
159
159
ZEND_ARG_INFO (0 , length )
160
160
ZEND_END_ARG_INFO ()
161
161
162
+ ZEND_BEGIN_ARG_INFO_EX (AI_KXClientSession , 0 , 0 , 2 )
163
+ ZEND_ARG_INFO (0 , client_keypair )
164
+ ZEND_ARG_INFO (0 , server_key )
165
+ ZEND_END_ARG_INFO ()
166
+
167
+ ZEND_BEGIN_ARG_INFO_EX (AI_KXServerSession , 0 , 0 , 2 )
168
+ ZEND_ARG_INFO (0 , server_keypair )
169
+ ZEND_ARG_INFO (0 , client_key )
170
+ ZEND_END_ARG_INFO ()
171
+
162
172
#if defined(HAVE_CRYPTO_AEAD_AES256GCM ) && defined(crypto_aead_aes256gcm_KEYBYTES ) && \
163
173
(defined(__amd64 ) || defined(__amd64__ ) || defined(__x86_64__ ) || defined(__i386__ ) || \
164
174
defined(_M_AMD64 ) || defined(_M_IX86 ))
@@ -195,7 +205,12 @@ const zend_function_entry sodium_functions[] = {
195
205
PHP_FE (sodium_crypto_box_seal_open , AI_StringAndKey )
196
206
#endif
197
207
PHP_FE (sodium_crypto_box_secretkey , AI_Key )
198
- PHP_FE (sodium_crypto_kx , AI_FourStrings )
208
+ PHP_FE (sodium_crypto_kx_keypair , AI_None )
209
+ PHP_FE (sodium_crypto_kx_publickey , AI_Key )
210
+ PHP_FE (sodium_crypto_kx_secretkey , AI_Key )
211
+ PHP_FE (sodium_crypto_kx_seed_keypair , AI_String )
212
+ PHP_FE (sodium_crypto_kx_client_session_keys , AI_KXClientSession )
213
+ PHP_FE (sodium_crypto_kx_server_session_keys , AI_KXServerSession )
199
214
PHP_FE (sodium_crypto_generichash , AI_StringAndMaybeKeyAndLength )
200
215
PHP_FE (sodium_crypto_generichash_init , AI_MaybeKeyAndLength )
201
216
PHP_FE (sodium_crypto_generichash_update , AI_StateByReferenceAndString )
@@ -368,12 +383,23 @@ PHP_MINIT_FUNCTION(sodium)
368
383
crypto_box_NONCEBYTES , CONST_CS | CONST_PERSISTENT );
369
384
REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_BOX_SEEDBYTES" ,
370
385
crypto_box_SEEDBYTES , CONST_CS | CONST_PERSISTENT );
371
- REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_KX_BYTES" ,
372
- crypto_kx_BYTES , CONST_CS | CONST_PERSISTENT );
386
+ #ifndef crypto_kx_SEEDBYTES
387
+ # define crypto_kx_SEEDBYTES 32
388
+ # define crypto_kx_SESSIONKEYBYTES 32
389
+ # define crypto_kx_PUBLICKEYBYTES 32
390
+ # define crypto_kx_SECRETKEYBYTES 32
391
+ #endif
392
+ REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_KX_SEEDBYTES" ,
393
+ crypto_kx_SEEDBYTES , CONST_CS | CONST_PERSISTENT );
394
+ REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_KX_SESSIONKEYBYTES" ,
395
+ crypto_kx_SESSIONKEYBYTES , CONST_CS | CONST_PERSISTENT );
373
396
REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_KX_PUBLICKEYBYTES" ,
374
397
crypto_kx_PUBLICKEYBYTES , CONST_CS | CONST_PERSISTENT );
375
398
REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_KX_SECRETKEYBYTES" ,
376
399
crypto_kx_SECRETKEYBYTES , CONST_CS | CONST_PERSISTENT );
400
+ REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_KX_KEYPAIRBYTES" ,
401
+ crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES ,
402
+ CONST_CS | CONST_PERSISTENT );
377
403
REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_GENERICHASH_BYTES" ,
378
404
crypto_generichash_BYTES , CONST_CS | CONST_PERSISTENT );
379
405
REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_GENERICHASH_BYTES_MIN" ,
@@ -2480,56 +2506,197 @@ PHP_FUNCTION(sodium_crypto_scalarmult)
2480
2506
RETURN_STR (q );
2481
2507
}
2482
2508
2483
- PHP_FUNCTION (sodium_crypto_kx )
2509
+ PHP_FUNCTION (sodium_crypto_kx_seed_keypair )
2510
+ {
2511
+ unsigned char * sk ;
2512
+ unsigned char * pk ;
2513
+ unsigned char * seed ;
2514
+ size_t seed_len ;
2515
+ zend_string * keypair ;
2516
+
2517
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "s" ,
2518
+ & seed , & seed_len ) == FAILURE ) {
2519
+ return ;
2520
+ }
2521
+ if (seed_len != crypto_kx_SEEDBYTES ) {
2522
+ zend_throw_exception (sodium_exception_ce , "seed must be CRYPTO_KX_SEEDBYTES bytes" , 0 );
2523
+ return ;
2524
+ }
2525
+ (void ) sizeof (int [crypto_scalarmult_SCALARBYTES == crypto_kx_PUBLICKEYBYTES ? 1 : -1 ]);
2526
+ (void ) sizeof (int [crypto_scalarmult_SCALARBYTES == crypto_kx_SECRETKEYBYTES ? 1 : -1 ]);
2527
+ keypair = zend_string_alloc (crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES , 0 );
2528
+ sk = (unsigned char * ) ZSTR_VAL (keypair );
2529
+ pk = sk + crypto_kx_SECRETKEYBYTES ;
2530
+ crypto_generichash (sk , crypto_kx_SECRETKEYBYTES ,
2531
+ seed , crypto_kx_SEEDBYTES , NULL , 0 );
2532
+ if (crypto_scalarmult_base (pk , sk ) != 0 ) {
2533
+ zend_throw_exception (sodium_exception_ce , "internal error" , 0 );
2534
+ return ;
2535
+ }
2536
+ ZSTR_VAL (keypair )[crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES ] = 0 ;
2537
+ RETURN_STR (keypair );
2538
+ }
2539
+
2540
+ PHP_FUNCTION (sodium_crypto_kx_keypair )
2541
+ {
2542
+ unsigned char * sk ;
2543
+ unsigned char * pk ;
2544
+ zend_string * keypair ;
2545
+
2546
+ keypair = zend_string_alloc (crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES , 0 );
2547
+ sk = (unsigned char * ) ZSTR_VAL (keypair );
2548
+ pk = sk + crypto_kx_SECRETKEYBYTES ;
2549
+ randombytes_buf (sk , crypto_kx_SECRETKEYBYTES );
2550
+ if (crypto_scalarmult_base (pk , sk ) != 0 ) {
2551
+ zend_throw_exception (sodium_exception_ce , "internal error" , 0 );
2552
+ return ;
2553
+ }
2554
+ RETURN_STR (keypair );
2555
+ }
2556
+
2557
+ PHP_FUNCTION (sodium_crypto_kx_secretkey )
2558
+ {
2559
+ zend_string * secretkey ;
2560
+ unsigned char * keypair ;
2561
+ size_t keypair_len ;
2562
+
2563
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "s" ,
2564
+ & keypair , & keypair_len ) == FAILURE ) {
2565
+ return ;
2566
+ }
2567
+ if (keypair_len !=
2568
+ crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES ) {
2569
+ zend_throw_exception (sodium_exception_ce ,
2570
+ "keypair should be CRYPTO_KX_KEYPAIRBYTES bytes" ,
2571
+ 0 );
2572
+ return ;
2573
+ }
2574
+ secretkey = zend_string_alloc (crypto_kx_SECRETKEYBYTES , 0 );
2575
+ memcpy (ZSTR_VAL (secretkey ), keypair , crypto_kx_SECRETKEYBYTES );
2576
+ ZSTR_VAL (secretkey )[crypto_kx_SECRETKEYBYTES ] = 0 ;
2577
+
2578
+ RETURN_STR (secretkey );
2579
+ }
2580
+
2581
+ PHP_FUNCTION (sodium_crypto_kx_publickey )
2582
+ {
2583
+ zend_string * publickey ;
2584
+ unsigned char * keypair ;
2585
+ size_t keypair_len ;
2586
+
2587
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "s" ,
2588
+ & keypair , & keypair_len ) == FAILURE ) {
2589
+ return ;
2590
+ }
2591
+ if (keypair_len !=
2592
+ crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES ) {
2593
+ zend_throw_exception (sodium_exception_ce ,
2594
+ "keypair should be CRYPTO_KX_KEYPAIRBYTES bytes" ,
2595
+ 0 );
2596
+ return ;
2597
+ }
2598
+ publickey = zend_string_alloc (crypto_kx_PUBLICKEYBYTES , 0 );
2599
+ memcpy (ZSTR_VAL (publickey ), keypair + crypto_kx_SECRETKEYBYTES ,
2600
+ crypto_kx_PUBLICKEYBYTES );
2601
+ ZSTR_VAL (publickey )[crypto_kx_PUBLICKEYBYTES ] = 0 ;
2602
+
2603
+ RETURN_STR (publickey );
2604
+ }
2605
+
2606
+ PHP_FUNCTION (sodium_crypto_kx_client_session_keys )
2484
2607
{
2485
2608
crypto_generichash_state h ;
2486
- unsigned char q [crypto_scalarmult_BYTES ];
2487
- zend_string * sharedkey ;
2488
- unsigned char * client_publickey ;
2489
- unsigned char * publickey ;
2490
- unsigned char * secretkey ;
2491
- unsigned char * server_publickey ;
2492
- size_t client_publickey_len ;
2493
- size_t publickey_len ;
2494
- size_t secretkey_len ;
2495
- size_t server_publickey_len ;
2609
+ unsigned char q [crypto_scalarmult_BYTES ];
2610
+ unsigned char * keypair ;
2611
+ unsigned char * client_sk ;
2612
+ unsigned char * client_pk ;
2613
+ unsigned char * server_pk ;
2614
+ unsigned char session_keys [2 * crypto_kx_SESSIONKEYBYTES ];
2615
+ size_t keypair_len ;
2616
+ size_t server_pk_len ;
2496
2617
2497
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "ssss" ,
2498
- & secretkey , & secretkey_len ,
2499
- & publickey , & publickey_len ,
2500
- & client_publickey , & client_publickey_len ,
2501
- & server_publickey , & server_publickey_len ) == FAILURE ) {
2618
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "ss" ,
2619
+ & keypair , & keypair_len ,
2620
+ & server_pk , & server_pk_len ) == FAILURE ) {
2502
2621
return ;
2503
2622
}
2504
- if (secretkey_len != crypto_kx_SECRETKEYBYTES ) {
2505
- zend_throw_exception (sodium_exception_ce , "crypto_kx(): secret key must be CRYPTO_KX_SECRETKEY bytes" , 0 );
2623
+ if (keypair_len != crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES ) {
2624
+ zend_throw_exception (sodium_exception_ce , "keypair must be CRYPTO_KX_KEYPAIRBYTES bytes" , 0 );
2506
2625
return ;
2507
2626
}
2508
- if (publickey_len != crypto_kx_PUBLICKEYBYTES ||
2509
- client_publickey_len != crypto_kx_PUBLICKEYBYTES ||
2510
- server_publickey_len != crypto_kx_PUBLICKEYBYTES ) {
2511
- zend_throw_exception (sodium_exception_ce , "crypto_kx(): public keys must be CRYPTO_KX_PUBLICKEY bytes" , 0 );
2627
+ if (server_pk_len != crypto_kx_PUBLICKEYBYTES ) {
2628
+ zend_throw_exception (sodium_exception_ce , "public keys must be CRYPTO_KX_PUBLICKEYBYTES bytes" , 0 );
2512
2629
return ;
2513
2630
}
2514
- ( void ) sizeof ( int [ crypto_scalarmult_SCALARBYTES ==
2515
- crypto_kx_PUBLICKEYBYTES ? 1 : -1 ]) ;
2516
- (void ) sizeof (int [crypto_scalarmult_SCALARBYTES ==
2517
- crypto_kx_SECRETKEYBYTES ? 1 : -1 ]);
2518
- if (crypto_scalarmult (q , secretkey , publickey ) != 0 ) {
2519
- zend_throw_exception (sodium_exception_ce , "crypto_kx(): internal error" , 0 );
2631
+ client_sk = & keypair [ 0 ];
2632
+ client_pk = & keypair [ crypto_kx_SECRETKEYBYTES ] ;
2633
+ (void ) sizeof (int [crypto_scalarmult_SCALARBYTES == crypto_kx_PUBLICKEYBYTES ? 1 : -1 ]);
2634
+ ( void ) sizeof ( int [ crypto_scalarmult_SCALARBYTES == crypto_kx_SECRETKEYBYTES ? 1 : -1 ]);
2635
+ if (crypto_scalarmult (q , client_sk , server_pk ) != 0 ) {
2636
+ zend_throw_exception (sodium_exception_ce , "internal error" , 0 );
2520
2637
return ;
2521
2638
}
2522
- sharedkey = zend_string_alloc (crypto_kx_BYTES , 0 );
2523
- crypto_generichash_init (& h , NULL , 0U , crypto_generichash_BYTES );
2639
+ crypto_generichash_init (& h , NULL , 0U , 2 * crypto_kx_SESSIONKEYBYTES );
2524
2640
crypto_generichash_update (& h , q , sizeof q );
2525
2641
sodium_memzero (q , sizeof q );
2526
- crypto_generichash_update (& h , client_publickey , client_publickey_len );
2527
- crypto_generichash_update (& h , server_publickey , server_publickey_len );
2528
- crypto_generichash_final (& h , (unsigned char * ) ZSTR_VAL (sharedkey ),
2529
- crypto_kx_BYTES );
2530
- ZSTR_VAL (sharedkey )[crypto_kx_BYTES ] = 0 ;
2642
+ crypto_generichash_update (& h , client_pk , crypto_kx_PUBLICKEYBYTES );
2643
+ crypto_generichash_update (& h , server_pk , crypto_kx_PUBLICKEYBYTES );
2644
+ crypto_generichash_final (& h , session_keys , 2 * crypto_kx_SESSIONKEYBYTES );
2645
+ array_init (return_value );
2646
+ add_next_index_stringl (return_value ,
2647
+ (const char * ) session_keys ,
2648
+ crypto_kx_SESSIONKEYBYTES );
2649
+ add_next_index_stringl (return_value ,
2650
+ (const char * ) session_keys + crypto_kx_SESSIONKEYBYTES ,
2651
+ crypto_kx_SESSIONKEYBYTES );
2652
+ }
2531
2653
2532
- RETURN_STR (sharedkey );
2654
+ PHP_FUNCTION (sodium_crypto_kx_server_session_keys )
2655
+ {
2656
+ crypto_generichash_state h ;
2657
+ unsigned char q [crypto_scalarmult_BYTES ];
2658
+ unsigned char * keypair ;
2659
+ unsigned char * server_sk ;
2660
+ unsigned char * server_pk ;
2661
+ unsigned char * client_pk ;
2662
+ unsigned char session_keys [2 * crypto_kx_SESSIONKEYBYTES ];
2663
+ size_t keypair_len ;
2664
+ size_t client_pk_len ;
2665
+
2666
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "ss" ,
2667
+ & keypair , & keypair_len ,
2668
+ & client_pk , & client_pk_len ) == FAILURE ) {
2669
+ return ;
2670
+ }
2671
+ if (keypair_len != crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES ) {
2672
+ zend_throw_exception (sodium_exception_ce , "keypair must be CRYPTO_KX_KEYPAIRBYTES bytes" , 0 );
2673
+ return ;
2674
+ }
2675
+ if (client_pk_len != crypto_kx_PUBLICKEYBYTES ) {
2676
+ zend_throw_exception (sodium_exception_ce , "public keys must be CRYPTO_KX_PUBLICKEYBYTES bytes" , 0 );
2677
+ return ;
2678
+ }
2679
+ server_sk = & keypair [0 ];
2680
+ server_pk = & keypair [crypto_kx_SECRETKEYBYTES ];
2681
+ (void ) sizeof (int [crypto_scalarmult_SCALARBYTES == crypto_kx_PUBLICKEYBYTES ? 1 : -1 ]);
2682
+ (void ) sizeof (int [crypto_scalarmult_SCALARBYTES == crypto_kx_SECRETKEYBYTES ? 1 : -1 ]);
2683
+ if (crypto_scalarmult (q , server_sk , client_pk ) != 0 ) {
2684
+ zend_throw_exception (sodium_exception_ce , "internal error" , 0 );
2685
+ return ;
2686
+ }
2687
+ crypto_generichash_init (& h , NULL , 0U , 2 * crypto_kx_SESSIONKEYBYTES );
2688
+ crypto_generichash_update (& h , q , sizeof q );
2689
+ sodium_memzero (q , sizeof q );
2690
+ crypto_generichash_update (& h , client_pk , crypto_kx_PUBLICKEYBYTES );
2691
+ crypto_generichash_update (& h , server_pk , crypto_kx_PUBLICKEYBYTES );
2692
+ crypto_generichash_final (& h , session_keys , 2 * crypto_kx_SESSIONKEYBYTES );
2693
+ array_init (return_value );
2694
+ add_next_index_stringl (return_value ,
2695
+ (const char * ) session_keys + crypto_kx_SESSIONKEYBYTES ,
2696
+ crypto_kx_SESSIONKEYBYTES );
2697
+ add_next_index_stringl (return_value ,
2698
+ (const char * ) session_keys ,
2699
+ crypto_kx_SESSIONKEYBYTES );
2533
2700
}
2534
2701
2535
2702
PHP_FUNCTION (sodium_crypto_auth )
0 commit comments