[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: SFL bug with 512-bit DSA Certificates



Jim,

We are investigating this issue and will provide further information
ASAP.

===========================================
John Pawling, John.Pawling@xxxxxxxxxxxxxxxx
Getronics Government Solutions, LLC
===========================================
 



-----Original Message-----
From: Jim Craigie [mailto:Jim.Craigie@xxxxxxxxxxxxxx]
Sent: Thursday, April 11, 2002 1:39 PM
To: Pawling, John
Cc: imc-sfl@xxxxxxx
Subject: Re: SFL bug with 512-bit DSA Certificates


John Stark writes:

Here are some details of where I have found assumptions within the SFL
2.0.1
code that DSA keys are always 1024-bit.  This list should not be
regarded as
definitive - there could be other code areas which I have not found that
also require attention to fix the problem.

The DSA/DSS spec can be found online at:
http://www.itl.nist.gov/fipspubs/fip186.htm
This indicates that DSA keys may be of any strength (== modulus size) in
the
range 512-1024 that is a multiple of 64.  However it is conventional to
use
powers of two (i.e. 512 or 1024).

SFL 2.0.1 file paths referred to below are relative to unpacked
distribution.  N.B. some of the line numbers could differ slightly in
the
original distribution since this information was taken from our source
that
has been ported to Solaris and had our own fixes applied.

1. SMIME/libCtilMgr/include/sm_apiCtilMgr.h, line 60:

  // Algorithm parameters
  oedefine SM_DSA_P_LEN       128
  oedefine SM_DSA_Q_LEN       20
  oedefine SM_DSA_G_LEN       128

In fact only Q is fixed at 20 bytes.  Both P and G may vary between 64
and
128 bytes.

2. SMIME/libCtilMgr/include/sm_CtilCommon.h, line 12:

  class LIBCTILMGRDLL_API CSM_DSAParams
  {
      public:
         char       *P;
         char       *Q;
         char       *G;
         CSM_DSAParams();
         ~CSM_DSAParams();
         SM_RET_VAL Decode(CSM_Buffer *pParams);
  };

This class has no data field to indicate the size of the P and G values.
Where code elsewhere uses DSA parameters in this class, it has to assume
the
oedefined values referred to above.

3. SMIME/libCtilMgr/src/sm_CtilCommon.cpp, line 57 in
CSM_DSAParams::Decode():

      if (pSnaccV3CertParams->p.Len() <= 65)
           pParamSize = 64;     // Smaller signature.
       else
           pParamSize = SM_DSA_P_LEN; // larger signature.

This code seems to assume that the size may be either 512-bit or
1024-bit.
Also pParamSize is a local variable that needs to be stored in the
CSM_DSAParams class as described above.  I have ignored the "V1
certificate"
code that makes extensive use of the hardwired lengths.

4. SMIME/alg_libs/sm_free3/sm_free3.cpp, line 509 in
CSM_Free3::SMTI_VerifyDSA():

     CSM_DSAParams dsaParameters;
      SME(dsaParameters.Decode(pParams));
      pP = new Integer((const unsigned char *)dsaParameters.P,
SM_DSA_P_LEN);
      pQ = new Integer((const unsigned char *)dsaParameters.Q,
SM_DSA_Q_LEN);
      pG = new Integer((const unsigned char *)dsaParameters.G,
SM_DSA_G_LEN);

This is, I believe, the code that actually causes the problem we observe
with our 512-bit certificates.  Because dsaParameters doesn't contain
the
length, this code has to assume the defaults for 1024-bit.  The Integers
that are constructed end up padded with garbage.

5. SMIME/alg_libs/sm_free3/sm_free3.cpp, line 2715 in
CSM_Free3::SetDSAParams():

  void CSM_Free3::SetDSAParams(AsnInt &P, AsnInt &Q, AsnInt &G)
  {
      CryptoPP::Integer *pTmpBI;
      pTmpBI = ComputeBigInteger(P, 128);
      m_DSAP = *pTmpBI;
      delete pTmpBI;
      pTmpBI = ComputeBigInteger(Q, 20);
      m_DSAQ = *pTmpBI;
      delete pTmpBI;
      pTmpBI = ComputeBigInteger(G, 128);
      m_DSAG = *pTmpBI;
      delete pTmpBI;
  }

This assumes numeric constant parameter sizes, not even the oedefined
values.

6. SMIME/alg_libs/sm_free3/sm_free3.cpp, line 3136 in
CSM_Free3::ExtractParams():

  else if (pAlgID->algorithm == id_dsa ||
            pAlgID->algorithm == id_dsa_with_sha1)
   {
      //byte *pbyte;
      // ASN.1 decode pParams as DSA parameters
      // store them in m_DSAP, m_DSAQ, and m_DSAG
      FREE_DSAParameters snaccDSAParams;
      DECODE_ANY((&snaccDSAParams), (pAlgID->parameters));
      // extract P
      Integer *pTmpBI;
      pTmpBI = ComputeBigInteger(snaccDSAParams.p, 128);
      //pbyte = (byte *)((char*)snaccDSAParams.p);
      m_DSAP = *pTmpBI; //RWC;.Decode(pbyte, snaccDSAParams.p.Len());
      delete pTmpBI;
      // extract Q
      pTmpBI = ComputeBigInteger(snaccDSAParams.q, 20);
      //pbyte = (byte *)((char*)snaccDSAParams.q);
      m_DSAQ = *pTmpBI; //RWC;.Decode(pbyte, snaccDSAParams.q.Len());
      delete pTmpBI;
      // extract G
      pTmpBI = ComputeBigInteger(snaccDSAParams.g, 128);
      //pbyte = (byte *)((char*)snaccDSAParams.g);
      m_DSAG = *pTmpBI; //RWC;.Decode(pbyte, snaccDSAParams.g.Len());
      delete pTmpBI;
   }

This similarly uses numeric constants for the parameter sizes.

Incidentally, the sm_free3.cpp source makes similar assumptions that
Diffie-Hellman keys are 1024-bit.  I have not listed these.

Finally, here is a code snippet illustrating my statement that the
content-encryption algorithm key sizes for Triple-DES and RC2 are fixed:

SMIME/alg_libs/sm_free3/sm_free3.cpp, line 849 in
CSM_Free3::EncryptCryptoPP():

      if (*pPreferredOID == des_ede3_cbc)
      {
         CBC_Length = SM_COMMON_3DES_BLOCKSIZE;
         CBC_KeyLength = SM_COMMON_3DES_KEYLEN;
      }
      else if (*pPreferredOID == rc2_cbc || *pPreferredOID ==
id_alg_CMSRC2wrap)
      {
         CBC_Length = SM_COMMON_RC2_BLOCKSIZE; // 8
         CBC_KeyLength = SM_COMMON_RC2_KEYLEN; // byte count 16
      }
      else if (*pPreferredOID == dES_CBC)
      {
         CBC_Length = SM_COMMON_3DES_BLOCKSIZE;
         CBC_KeyLength = 8;                     // for DES.
      }
      else          // Default to 3DES length.
      {
         CBC_Length = SM_COMMON_3DES_BLOCKSIZE;
         CBC_KeyLength = SM_COMMON_3DES_KEYLEN;
      }


John Stark
E-mail: jas@xxxxxxxxxxxx
Tel: +44 (0) 1223 566732
Fax: +44 (0) 1223 566727
Mobile: +44 (0) 7968 110628



-----------------------------------------------------------------------

Clearswift monitors, controls and protects all its messaging traffic in
compliance with its 
corporate email policy using Clearswift products. Find out more about
Clearswift, its 
solutions and services at http://www.clearswift.com

************************************************************************
********************************
This communication is confidential and may contain privileged
information intended solely 
for the named addressee(s). It may not be used or disclosed except for
the purpose for 
which it has been sent. If you are not the intended recipient, you must
not copy, distribute 
or take any action in reliance on it. Unless expressly stated, opinions
in this message are 
those of the individual sender and not of Clearswift. If you have
received this communication
in error, please notify Clearswift by emailing support@xxxxxxxxxxxxxx
quoting the sender and
delete the message and any attached documents. Clearswift accepts no
liability or 
responsibility for any onward transmission or use of emails and
attachments having left the 
Clearswift domain.