JDK-6832016 : {DigestMD5Base,Des3DkCrypto}.setParityBit should use Integer.bitCount
  • Type: Enhancement
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 7
  • Priority: P5
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2009-04-20
  • Updated: 2013-11-01
  • Resolved: 2009-06-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b62Fixed
Related Reports
Relates :  
Description
DigestMD5Base.setParityBit and Des3DkCrypto.setParityBit should use the Integer.bitCount method, as e.g. DESKeyGenerator.setParityBit does.  The implementation would be much cleaner and faster, especially with HS15 on newer CPUs that implement a population count instruction (see 6378821).

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/tl/jdk/rev/02b02a886b9b Fixed as suggested by the bug reporter. No new regression test, already covered by existing tests.
20-05-2009

SUGGESTED FIX diff -Nupr jdk.22b6e09960c1/src/share/classes/com/sun/security/sasl/digest/DigestMD5Base.java jdk/src/share/classes/com/sun/security/sasl/digest/DigestMD5Base.java --- jdk.22b6e09960c1/src/share/classes/com/sun/security/sasl/digest/DigestMD5Base.java 2009-04-20 14:28:41.735605303 +0200 +++ jdk/src/share/classes/com/sun/security/sasl/digest/DigestMD5Base.java 2009-04-20 14:28:41.741543397 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1516,11 +1516,6 @@ abstract class DigestMD5Base extends Abs // ---------------- DES and 3 DES key manipulation routines - /* Mask used to check for parity adjustment */ - private static final byte[] PARITY_BIT_MASK = { - (byte)0x80, (byte)0x40, (byte)0x20, (byte)0x10, - (byte)0x08, (byte)0x04, (byte)0x02 - }; private static final BigInteger MASK = new BigInteger("7f", 16); /** @@ -1529,21 +1524,9 @@ abstract class DigestMD5Base extends Abs */ private static void setParityBit(byte[] key) { for (int i = 0; i < key.length; i++) { - int bitCount = 0; - for (int maskIndex = 0; - maskIndex < PARITY_BIT_MASK.length; maskIndex++) { - if ((key[i] & PARITY_BIT_MASK[maskIndex]) - == PARITY_BIT_MASK[maskIndex]) { - bitCount++; - } - } - if ((bitCount & 0x01) == 1) { - // Odd number of 1 bits in the top 7 bits. Set parity bit to 0 - key[i] = (byte)(key[i] & (byte)0xfe); - } else { - // Even number of 1 bits in the top 7 bits. Set parity bit to 1 - key[i] = (byte)(key[i] | 1); - } + int b = key[i] & 0xfe; + b |= (Integer.bitCount(b) & 1) ^ 1; + key[i] = (byte) b; } } diff -Nupr jdk.22b6e09960c1/src/share/classes/sun/security/krb5/internal/crypto/dk/Des3DkCrypto.java jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/Des3DkCrypto.java --- jdk.22b6e09960c1/src/share/classes/sun/security/krb5/internal/crypto/dk/Des3DkCrypto.java 2009-04-20 14:28:41.739465575 +0200 +++ jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/Des3DkCrypto.java 2009-04-20 14:28:41.743159244 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -169,33 +169,15 @@ public class Des3DkCrypto extends DkCryp return result; } - /* Mask used to check for parity adjustment */ - private static final byte[] PARITY_BIT_MASK = { - (byte)0x80, (byte)0x40, (byte)0x20, (byte)0x10, - (byte)0x08, (byte)0x04, (byte)0x02 - }; - /** * Sets the parity bit (0th bit) in each byte so that each byte * contains an odd number of 1's. */ private static void setParityBit(byte[] key) { for (int i = 0; i < key.length; i++) { - int bitCount = 0; - for (int maskIndex = 0; - maskIndex < PARITY_BIT_MASK.length; maskIndex++) { - if ((key[i] & PARITY_BIT_MASK[maskIndex]) - == PARITY_BIT_MASK[maskIndex]) { - bitCount++; - } - } - if ((bitCount & 0x01) == 1) { - // Odd number of 1 bits in the top 7 bits. Set parity bit to 0 - key[i] = (byte)(key[i] & (byte)0xfe); - } else { - // Even number of 1 bits in the top 7 bits. Set parity bit to 1 - key[i] = (byte)(key[i] | 1); - } + int b = key[i] & 0xfe; + b |= (Integer.bitCount(b) & 1) ^ 1; + key[i] = (byte) b; } }
20-04-2009