RFC 3414 [ User-based Security Model (USM) SNMPv3 ]

"poojan_tanna" <[email protected]> Wed, 8 Jan 2003 16:20:27 +0530
Newsgroups gmane.ietf.snmpv3
Message-ID <[email protected]>
Hi,

  This is regarding RFC 3414 [ User-based Security Model (USM) for version 3 of the Simple Network Management Protocol (SNMPv3) ]. 

There is a interesting Password to Key Generation Algorithm mentioned in this
RFC.

Excerpt from RFC 3414 is as follows:
-------------------------------------------------------------------------------
A.2.1. Password to Key Sample Code for MD5

   void password_to_key_md5(
      u_char *password,    /* IN */
      u_int   passwordlen, /* IN */
      u_char *engineID,    /* IN  - pointer to snmpEngineID  */
      u_int   engineLength,/* IN  - length of snmpEngineID */
      u_char *key)         /* OUT - pointer to caller 16-octet buffer */
   {
      MD5_CTX     MD;
      u_char     *cp, password_buf[64];
      u_long      password_index = 0;
      u_long      count = 0, i;

      MD5Init (&MD);   /* initialize MD5 */

      /**********************************************/
      /* Use while loop until we've done 1 Megabyte */
      /**********************************************/
      while (count < 1048576) {
         cp = password_buf;
         for (i = 0; i < 64; i++) {
             /*************************************************/
             /* Take the next octet of the password, wrapping */
             /* to the beginning of the password as necessary.*/
             /*************************************************/
             *cp++ = password[password_index++ % passwordlen];
         }
         MD5Update (&MD, password_buf, 64);
         count += 64;
      }
      MD5Final (key, &MD);          /* tell MD5 we're done */

      /*****************************************************/
      /* Now localize the key with the engineID and pass   */
      /* through MD5 to produce final key                  */
      /* May want to ensure that engineLength <= 32,       */
      /* otherwise need to use a buffer larger than 64     */
      /*****************************************************/
      memcpy(password_buf, key, 16);
      memcpy(password_buf+16, engineID, engineLength);
      memcpy(password_buf+16+engineLength, key, 16);

      MD5Init(&MD);
      MD5Update(&MD, password_buf, 32+engineLength);
      MD5Final(key, &MD);
      return;
   }

-----------------------------------------------------------------------------
If a user specifies a password, then the user's password is converted into a key using the above algorithm.

The implementation is such that it gives the same key for recursive passwords.

e.g.  if the password is "passwd" then key generated is
"O8u\x08\xca_\xd6{\xec\xbd\x1c\xb4\xd9\xec\xf2I".

Now if the password is changed to "passwdpasswd" then the key generated will be the same i.e "O8u\x08\xca_\xd6{\xec\xbd\x1c\xb4\xd9\xec\xf2I"

Thus if the password is "passwd" or "passwdpasswd" or "paswdpasswdpasswd" and so on, the key generated will be the same in all the cases.

I suppose that this is due to the following 'for' loop in the above mentioned
RFC excerpt:
         for (i = 0; i < 64; i++) {
             /*************************************************/
             /* Take the next octet of the password, wrapping */
             /* to the beginning of the password as necessary.*/
             /*************************************************/
             *cp++ = password[password_index++ % passwordlen];
         }

Your views on this will be highly appreciated.

Thanks,
Poojan.