@@ -131,13 +131,42 @@ static int pqdsa_pub_encode(CBB *out, const EVP_PKEY *pkey) {
131131 return 1 ;
132132}
133133
134+ // pqdsa_cmp_parameters returns 1 if |a| and |b| hold populated PQDSA keys
135+ // with the same ML-DSA NID, 0 if their NIDs differ, or -2 if either operand
136+ // is missing its key or parameters. The tri-state return aligns with the
137+ // |EVP_PKEY_cmp| convention (1 = equal, 0 = not equal, negative = error).
138+ static int pqdsa_cmp_parameters (const EVP_PKEY * a , const EVP_PKEY * b ) {
139+ if (a == NULL || b == NULL ) {
140+ return -2 ;
141+ }
142+ const PQDSA_KEY * a_key = a -> pkey .pqdsa_key ;
143+ const PQDSA_KEY * b_key = b -> pkey .pqdsa_key ;
144+ if (a_key == NULL || b_key == NULL ) {
145+ return -2 ;
146+ }
147+
148+ const PQDSA * a_pqdsa = a_key -> pqdsa ;
149+ const PQDSA * b_pqdsa = b_key -> pqdsa ;
150+ if (a_pqdsa == NULL || b_pqdsa == NULL ) {
151+ return -2 ;
152+ }
153+
154+ return a_pqdsa -> nid == b_pqdsa -> nid ;
155+ }
156+
134157static int pqdsa_pub_cmp (const EVP_PKEY * a , const EVP_PKEY * b ) {
135- PQDSA_KEY * a_key = a -> pkey .pqdsa_key ;
136- PQDSA_KEY * b_key = b -> pkey .pqdsa_key ;
158+ int ret = pqdsa_cmp_parameters (a , b );
159+ if (ret <= 0 ) {
160+ return ret ;
161+ }
137162
138- return OPENSSL_memcmp (a_key -> public_key ,
139- b_key -> public_key ,
140- a -> pkey .pqdsa_key -> pqdsa -> public_key_len ) == 0 ;
163+ const PQDSA_KEY * a_key = a -> pkey .pqdsa_key ;
164+ const PQDSA_KEY * b_key = b -> pkey .pqdsa_key ;
165+ if (a_key -> public_key == NULL || b_key -> public_key == NULL ) {
166+ return -2 ;
167+ }
168+ return OPENSSL_memcmp (a_key -> public_key , b_key -> public_key ,
169+ a_key -> pqdsa -> public_key_len ) == 0 ;
141170}
142171
143172static int pqdsa_priv_decode (EVP_PKEY * out , CBS * oid , CBS * params , CBS * key , CBS * pubkey ) {
0 commit comments