@@ -792,6 +792,109 @@ int test_ecx_x25519_raw_priv_roundtrip(void *data)
792792 return err ;
793793}
794794
795+ /* get_params must size the export buffer from the caller's data_size, not
796+ * return_size. A reused param can carry a stale/zero return_size from a prior
797+ * size query; using it would truncate or fail the export. */
798+ int test_ecx_x25519_get_params_stale_ret (void * data )
799+ {
800+ int err = 0 ;
801+ EVP_PKEY * pkey = NULL ;
802+ static const unsigned char privKey [] = {
803+ 0x77 , 0x07 , 0x6d , 0x0a , 0x73 , 0x18 , 0xa5 , 0x7d ,
804+ 0x3c , 0x16 , 0xc1 , 0x72 , 0x51 , 0xb2 , 0x66 , 0x45 ,
805+ 0xdf , 0x4c , 0x2f , 0x87 , 0xeb , 0xc0 , 0x99 , 0x2a ,
806+ 0xb1 , 0x77 , 0xfb , 0xa5 , 0x1d , 0xb9 , 0x2c , 0x2a
807+ };
808+ /* RFC 7748 Section 6.1 Alice public key, derived from privKey above. */
809+ static const unsigned char pubKey [] = {
810+ 0x85 , 0x20 , 0xf0 , 0x09 , 0x89 , 0x30 , 0xa7 , 0x54 ,
811+ 0x74 , 0x8b , 0x7d , 0xdc , 0xb4 , 0x3e , 0xf7 , 0x5a ,
812+ 0x0d , 0xbf , 0x3a , 0x0d , 0x26 , 0x38 , 0x1a , 0xf4 ,
813+ 0xeb , 0xa4 , 0xa9 , 0x8e , 0xaa , 0x9b , 0x4e , 0x6a
814+ };
815+ unsigned char readback [32 ];
816+ OSSL_PARAM params [2 ];
817+
818+ (void )data ;
819+
820+ PRINT_MSG ("X25519 get_params with stale (zero) return_size" );
821+
822+ pkey = EVP_PKEY_new_raw_private_key_ex (wpLibCtx , "X25519" , NULL ,
823+ privKey , sizeof (privKey ));
824+ if (pkey == NULL ) {
825+ PRINT_ERR_MSG ("Failed to import X25519 private key" );
826+ err = 1 ;
827+ }
828+
829+ /* Private key: full 32-byte buffer but return_size forced to 0. */
830+ if (err == 0 ) {
831+ memset (readback , 0 , sizeof (readback ));
832+ params [0 ] = OSSL_PARAM_construct_octet_string (
833+ OSSL_PKEY_PARAM_PRIV_KEY , readback , sizeof (readback ));
834+ params [0 ].return_size = 0 ;
835+ params [1 ] = OSSL_PARAM_construct_end ();
836+ if (EVP_PKEY_get_params (pkey , params ) != 1 ) {
837+ PRINT_ERR_MSG ("priv key get_params failed with stale return_size" );
838+ err = 1 ;
839+ }
840+ }
841+ if (err == 0 && params [0 ].return_size != sizeof (privKey )) {
842+ PRINT_ERR_MSG ("priv key return_size wrong: %zu" , params [0 ].return_size );
843+ err = 1 ;
844+ }
845+ if (err == 0 && memcmp (readback , privKey , sizeof (privKey )) != 0 ) {
846+ PRINT_ERR_MSG ("priv key bytes not returned correctly" );
847+ err = 1 ;
848+ }
849+
850+ /* Public key: same stale-return_size condition on the export path. */
851+ if (err == 0 ) {
852+ memset (readback , 0 , sizeof (readback ));
853+ params [0 ] = OSSL_PARAM_construct_octet_string (
854+ OSSL_PKEY_PARAM_PUB_KEY , readback , sizeof (readback ));
855+ params [0 ].return_size = 0 ;
856+ params [1 ] = OSSL_PARAM_construct_end ();
857+ if (EVP_PKEY_get_params (pkey , params ) != 1 ) {
858+ PRINT_ERR_MSG ("pub key get_params failed with stale return_size" );
859+ err = 1 ;
860+ }
861+ }
862+ if (err == 0 && params [0 ].return_size != sizeof (pubKey )) {
863+ PRINT_ERR_MSG ("pub key return_size wrong: %zu" , params [0 ].return_size );
864+ err = 1 ;
865+ }
866+ if (err == 0 && memcmp (readback , pubKey , sizeof (pubKey )) != 0 ) {
867+ PRINT_ERR_MSG ("pub key bytes not returned correctly" );
868+ err = 1 ;
869+ }
870+
871+ /* Encoded public key: same helper, exercised via its own key string. */
872+ if (err == 0 ) {
873+ memset (readback , 0 , sizeof (readback ));
874+ params [0 ] = OSSL_PARAM_construct_octet_string (
875+ OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY , readback , sizeof (readback ));
876+ params [0 ].return_size = 0 ;
877+ params [1 ] = OSSL_PARAM_construct_end ();
878+ if (EVP_PKEY_get_params (pkey , params ) != 1 ) {
879+ PRINT_ERR_MSG ("enc pub key get_params failed with stale "
880+ "return_size" );
881+ err = 1 ;
882+ }
883+ }
884+ if (err == 0 && params [0 ].return_size != sizeof (pubKey )) {
885+ PRINT_ERR_MSG ("enc pub key return_size wrong: %zu" ,
886+ params [0 ].return_size );
887+ err = 1 ;
888+ }
889+ if (err == 0 && memcmp (readback , pubKey , sizeof (pubKey )) != 0 ) {
890+ PRINT_ERR_MSG ("enc pub key bytes not returned correctly" );
891+ err = 1 ;
892+ }
893+
894+ EVP_PKEY_free (pkey );
895+ return err ;
896+ }
897+
795898/* A zero-length private key octet string must be rejected without an
796899 * out-of-bounds read (privData[len-1] with len==0). */
797900int test_ecx_import_zero_priv (void * data )
0 commit comments