@@ -571,58 +571,33 @@ static int wp_x25519_derive(wp_EcxCtx* ctx, unsigned char* secret,
571571 fflush (stderr );
572572 }
573573
574- /* CRITICAL FIX: Force-clear MSB on BOTH keys right before calling shared_secret */
575- /* wc_curve25519_shared_secret checks MSB from internal key structure, not exported bytes */
576- /* Even if exported bytes show MSB clear, internal structure might have it set */
577- fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] Force-clearing MSB on both keys before shared_secret call...\n" );
578- fflush (stderr );
579-
580- if (ok && pre_call_local_rc == 0 && pre_call_peer_rc == 0 ) {
581- /* Force-clear MSB on LOCAL key's public key */
582- byte local_pub_fixed [CURVE25519_KEYSIZE ];
583- XMEMCPY (local_pub_fixed , pre_call_local_pub , CURVE25519_KEYSIZE );
584- local_pub_fixed [CURVE25519_KEYSIZE - 1 ] &= 0x7f ;
585- fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] LOCAL key - before fix: 0x%02x, after fix: 0x%02x\n" ,
586- pre_call_local_pub [CURVE25519_KEYSIZE - 1 ], local_pub_fixed [CURVE25519_KEYSIZE - 1 ]);
587- fflush (stderr );
588- /* Re-import LOCAL public key with MSB cleared */
589- int rc_local_fix = wc_curve25519_import_public_ex (local_pub_fixed , CURVE25519_KEYSIZE , local_key , EC25519_LITTLE_ENDIAN );
590- fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] LOCAL key re-import with MSB cleared: rc=%d\n" , rc_local_fix );
591- fflush (stderr );
592-
593- /* Force-clear MSB on PEER key's public key */
594- byte peer_pub_fixed [CURVE25519_KEYSIZE ];
595- XMEMCPY (peer_pub_fixed , pre_call_peer_pub , CURVE25519_KEYSIZE );
596- peer_pub_fixed [CURVE25519_KEYSIZE - 1 ] &= 0x7f ;
597- fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] PEER key - before fix: 0x%02x, after fix: 0x%02x\n" ,
598- pre_call_peer_pub [CURVE25519_KEYSIZE - 1 ], peer_pub_fixed [CURVE25519_KEYSIZE - 1 ]);
599- fflush (stderr );
600- /* Re-import PEER public key with MSB cleared */
601- int rc_peer_fix = wc_curve25519_import_public_ex (peer_pub_fixed , CURVE25519_KEYSIZE , peer_key_derive , EC25519_LITTLE_ENDIAN );
602- fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] PEER key re-import with MSB cleared: rc=%d\n" , rc_peer_fix );
603- fflush (stderr );
604-
605- if (rc_local_fix != 0 || rc_peer_fix != 0 ) {
606- fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] ERROR - Failed to re-import keys with MSB cleared! local_rc=%d, peer_rc=%d\n" ,
607- rc_local_fix , rc_peer_fix );
574+ /* NOTE: We do NOT normalize the local key here because:
575+ * 1. The local key already has both public and private keys
576+ * 2. Re-importing only the public key can corrupt the key structure
577+ * 3. The local key was generated properly and should already have MSB clear
578+ *
579+ * The peer key should already be normalized in wp_ecx_set_peer, but we check
580+ * and normalize only if MSB is actually set (to avoid unnecessary operations).
581+ */
582+ if (ok && pre_call_peer_rc == 0 ) {
583+ /* Only normalize peer key if MSB is actually set */
584+ if (pre_call_peer_pub [CURVE25519_KEYSIZE - 1 ] & 0x80 ) {
585+ fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] Peer key has MSB set, normalizing...\n" );
608586 fflush (stderr );
609- ok = 0 ;
610- } else {
611- /* Verify the fix worked */
612- word32 verify_local_len = CURVE25519_KEYSIZE ;
613- word32 verify_peer_len = CURVE25519_KEYSIZE ;
614- byte verify_local [CURVE25519_KEYSIZE ];
615- byte verify_peer [CURVE25519_KEYSIZE ];
616- int verify_local_rc = wc_curve25519_export_public_ex (local_key , verify_local , & verify_local_len , EC25519_LITTLE_ENDIAN );
617- int verify_peer_rc = wc_curve25519_export_public_ex (peer_key_derive , verify_peer , & verify_peer_len , EC25519_LITTLE_ENDIAN );
618- if (verify_local_rc == 0 && verify_peer_rc == 0 ) {
619- fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] Verification after fix - LOCAL last_byte=0x%02x (MSB=%s), PEER last_byte=0x%02x (MSB=%s)\n" ,
620- verify_local [CURVE25519_KEYSIZE - 1 ],
621- (verify_local [CURVE25519_KEYSIZE - 1 ] & 0x80 ) ? "SET" : "CLEAR" ,
622- verify_peer [CURVE25519_KEYSIZE - 1 ],
623- (verify_peer [CURVE25519_KEYSIZE - 1 ] & 0x80 ) ? "SET" : "CLEAR" );
587+
588+ byte peer_pub_fixed [CURVE25519_KEYSIZE ];
589+ XMEMCPY (peer_pub_fixed , pre_call_peer_pub , CURVE25519_KEYSIZE );
590+ peer_pub_fixed [CURVE25519_KEYSIZE - 1 ] &= 0x7f ;
591+
592+ int rc_peer_fix = wc_curve25519_import_public_ex (peer_pub_fixed , CURVE25519_KEYSIZE , peer_key_derive , EC25519_LITTLE_ENDIAN );
593+ if (rc_peer_fix != 0 ) {
594+ fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] ERROR - Failed to normalize peer key! rc=%d\n" , rc_peer_fix );
624595 fflush (stderr );
596+ ok = 0 ;
625597 }
598+ } else {
599+ fprintf (stderr , "[X25519-DEBUG] wp_x25519_derive: [BEFORE] Peer key MSB already clear, no normalization needed\n" );
600+ fflush (stderr );
626601 }
627602 }
628603
0 commit comments