@@ -137,13 +137,42 @@ static int pqdsa_pub_encode(CBB *out, const EVP_PKEY *pkey) {
137137 return 1 ;
138138}
139139
140+ // pqdsa_cmp_parameters returns 1 if |a| and |b| hold populated PQDSA keys
141+ // with the same ML-DSA NID, 0 if their NIDs differ, or -2 if either operand
142+ // is missing its key or parameters. The tri-state return aligns with the
143+ // |EVP_PKEY_cmp| convention (1 = equal, 0 = not equal, negative = error).
144+ static int pqdsa_cmp_parameters (const EVP_PKEY * a , const EVP_PKEY * b ) {
145+ if (a == NULL || b == NULL ) {
146+ return -2 ;
147+ }
148+ const PQDSA_KEY * a_key = a -> pkey .pqdsa_key ;
149+ const PQDSA_KEY * b_key = b -> pkey .pqdsa_key ;
150+ if (a_key == NULL || b_key == NULL ) {
151+ return -2 ;
152+ }
153+
154+ const PQDSA * a_pqdsa = a_key -> pqdsa ;
155+ const PQDSA * b_pqdsa = b_key -> pqdsa ;
156+ if (a_pqdsa == NULL || b_pqdsa == NULL ) {
157+ return -2 ;
158+ }
159+
160+ return a_pqdsa -> nid == b_pqdsa -> nid ;
161+ }
162+
140163static int pqdsa_pub_cmp (const EVP_PKEY * a , const EVP_PKEY * b ) {
141- PQDSA_KEY * a_key = a -> pkey .pqdsa_key ;
142- PQDSA_KEY * b_key = b -> pkey .pqdsa_key ;
164+ int ret = pqdsa_cmp_parameters (a , b );
165+ if (ret <= 0 ) {
166+ return ret ;
167+ }
143168
144- return OPENSSL_memcmp (a_key -> public_key ,
145- b_key -> public_key ,
146- a -> pkey .pqdsa_key -> pqdsa -> public_key_len ) == 0 ;
169+ const PQDSA_KEY * a_key = a -> pkey .pqdsa_key ;
170+ const PQDSA_KEY * b_key = b -> pkey .pqdsa_key ;
171+ if (a_key -> public_key == NULL || b_key -> public_key == NULL ) {
172+ return -2 ;
173+ }
174+ return OPENSSL_memcmp (a_key -> public_key , b_key -> public_key ,
175+ a_key -> pqdsa -> public_key_len ) == 0 ;
147176}
148177
149178static int pqdsa_priv_decode (EVP_PKEY * out , CBS * oid , CBS * params , CBS * key , CBS * pubkey ) {
0 commit comments