SNMPv3 -- User Security Model

This is the first of two articles describing the security features of the SNMP version 3 protocol. The SNMPv3 RFCs describe a new framework that is used for defining the relationships between the SNMP versions 1, 2, and 3 specifications. This framework is partitioned in a modular fashion and is heavily based on previous work (i.e., SNMPv1, SNMPv2c, SNMPv2u, and SNMPv2*).


April 09, 2004
URL:http://www.drdobbs.com/snmpv3-user-security-model/199100972

SNMPv3 -- User Security Model

Eric Davis

This is the first of two articles describing the security features of the SNMP version 3 protocol. The SNMPv3 RFCs describe a new framework that is used for defining the relationships between the SNMP versions 1, 2, and 3 specifications. This framework is partitioned in a modular fashion and is heavily based on previous work (i.e., SNMPv1, SNMPv2c, SNMPv2u, and SNMPv2*).

Two core modules within the framework are the User-based Security Model (USM) and the View-based Access Control Model (VACM). The USM is in charge of authenticating, encrypting, and decrypting SNMP packets, and the VACM is in charge of administering access to MIB data. This article gives an overview of the USM. Next month we will take a look at the VACM.

The USM is specified in RFC 2574. A weak point of all the previous well-known SNMP versions has been the lack of a solid, agreed upon security scheme. In designing the USM, these classic security threats had to be addressed:

The USM is able to protect SNMPv3 packets from the above threats by utilizing a concept of multiple users where each user provides secret keys for authentication and privacy. The authentication protocols specified for use are HMAC-MD5 and HMAC-SHA. The privacy protocol specified is CBC-DES. The RFC states that the security protocols used for the USM are considered acceptably secure at the time of its writing. However, the model allows for new authentication and privacy protocols to be specified at a future time if the need arises.

Concepts

The SNMPv3 framework introduces many new concepts. Most of these concepts are used by multiple modules within the framework. Here are a few that are used by the USM:

SNMPv3 Packet Format

The SNMP packet structure for version 3 has been changed to accommodate the use of a security model like the USM (see Figure 1).

USM Security Parameters

The USM uses the msgSecurityParameters to hold five values. These values are used by the authentication module to ensure data integrity and origin authentication, by the timeliness module to protect against message delay or replay, and by the privacy module to protect against message payload disclosure.

Agent Discovery

As mentioned above, the USM requires that the snmpEngineID, snmpEngineBoots, and snmpEngineTime of the authoritative engine be placed in the msgSecurityParameters. This requires the non-authoritative engine (i.e., manager) to know these values for the authoritative engine (i.e., agent) before a GET, NEXT, or SET operation can be completed.

This is achieved by a discovery process. There are two discovery transactions that occur. The first is to discover the snmpEngineID of the agent. The second is to discover the snmpEngineBoots and snmpEngineTime. The second transaction is only needed if the manager wants to use a security level of authNoPriv or authPriv. This is because the msgAuthoritativeEngineBoots and msgAuthoritativeEngineTime are used by the timeliness module, which is part of the authentication process.

The first discovery transaction is initiated by the manager sending an SNMPv3 packet with the msgAuthoritativeEngineID containing a bogus value. When the agent receives a packet where the msgAuthoritativeEngineID is different from its own, the packet is discarded and a discovery packet is returned to the manager. The returned discovery packet contains the correct snmpEngineID, which must be used by the manager.

The second discovery transaction requires an authenticated packet to be sent to the agent. This means that the authentication flag is set in the msgFlags, and the msgAuthenticationParameters contains the computed message digest for the packet. The secret key used for authenticating the packet is from the user specified in msgUserName. What makes this a discovery packet is that the msgAuthoritativeEngineBoots and msgAuthoritativeEngineTime contain bogus values. When the agent receives this packet, it is first authenticated. Once the authentication is completed, the msgAuthoritativeEngineBoots and msgAuthoritativeEngineTime values are checked. Since the values are bogus, the packet is discarded and a second discovery packet is returned to the manager. The returned discovery packet is authenticated, using the same user, and contains the correct values of the snmpEngineBoots and snmpEngineTime, which must be used by the manager.

Timeliness

Once a manager has learned the snmpEngineBoots and snmpEngineTime of an agent, the manager must maintain its own local notion of what these values are supposed to be. This requires the manager to increment the learned snmpEngineTime every second, so the value will be very close to the master values maintained by the agent. If the snmpEngineTime rolls over, then the snmpEngineBoots must be incremented. A manager must keep local notions of these values for each agent in which it wishes to communicate.

The timeliness checks by an agent are considered part of the authentication process and are done right after the received packet has been authenticated. If the msgAuthoritativeEngineBoots is different from the agent's current value of the snmpEngineBoots, the packet is discarded and a discovery packet is sent back to the manager. If that check passes, then the msgAuthoritativeEngineTime is checked against the agent's current value of the snmpEngineTime. If the difference between the two is more or less than 150 seconds, the packet is discarded and a discovery packet is sent back to the manager. If both of the checks pass, then the packet is considered to have been received in a timely manner and processing continues.

The value of +/- 150 seconds for the comparison of the snmpEngineTime is the default value specified by the RFC. This value could be modified to something more suitable based on the speed and size of your network.

Authentication

The USM specifies the use of the Message Digest 5 (MD5) and Secure Hash Algorithm 1 (SHA-1) algorithms for authenticating SNMPv3 packets. These algorithms are used to create unique fixed-sized message digests, also called digital signatures or fingerprints, of a variable length message. MD5 creates a digest of 128 bits (16 bytes), and SHA-1 creates a digest of 160 bits (20 bytes). Both MD5 and SHA-1 cannot be used directly as a message authentication code because they do not use secret keys as input to derivate the computed message digest. This is why the Keyed Hashing for Message Authentication (HMAC) algorithm in combination with MD5 and SHA-1 is used for computing message digests. The HMAC algorithm defines a procedure for appending a secret key to the data and then computing the MD5 or SHA-1 message digest. This guarantees that parties who wish to compute identical message digests for the same block of data must share a common secret key. Here are the steps that are taken for sending and receiving an authenticated SNMPv3 packet.

Sending an authenticated SNMPv3 packet:

1. The entire packet is created. The authentication flag is turned on in the msgFlags, and the msgAuthenticationParameters is zeroed out.

2. A message digest is computed of the packet using the secret authentication key for the user specified in msgUserName. The algorithm used (e.g., HMAC-MD5 or HMAC-SHA) is determined by the authentication protocol specified for the user in the User Table.

3. The computed message digest is inserted in the msgAuthenticationParameters.

4. The packet is sent.

Receiving an authenticated SNMPv3 packet:

1. The packet is received.

2. If the authentication flag is turned on in the msgFlags, then continue with the authentication process at step 3. If the packet was not authenticated by the sender, authentication is skipped.

3. The msgAuthenticationParameters is saved.

4. The msgAuthenticationParameters is zeroed out.

5. A message digest is computed of the packet using the secret authentication key for the user specified in msgUserName. The algorithm used (e.g., HMAC-MD5 or HMAC-SHA) is determined by the authentication protocol specified for the user in the User Table. If the user does not exist in the User Table, then the packet can not be authenticated and it is dropped.

6. The computed message digest is compared to the previously saved msgAuthenticationParameters. If they are different, then the packet is not authentic and it is dropped. If they are the same, then the packet is authentic and processing may continue.

Privacy

The USM specifies the use of the Cipher Block Chaining mode to the Data Encryption Standard (CBC-DES) algorithm for encrypting and decrypting SNMPv3 packets. The scope of the encryption only covers the scopedPDU, which contains the PDU and context data used by the VACM. The DES algorithm takes three inputs. These inputs are the data to be encrypted, a 56-bit secret key, and a 56-bit randomly generated salt used to ensure that two different initialization vectors are used for two different data inputs encrypted with the same secret key. For two parties to use encryption during communication, each must share a secret privacy key as well as the salt used to derivate the initialization vector. The secret privacy keys are stored in the User Table, and the salt is transmitted with the packet in the msgPrivacyParameters. Here are the steps that are taken for sending and receiving an encrypted packet.

Sending an encrypted SNMPv3 packet:

1. The entire packet is created, and the authentication and privacy flags are turned on in the msgFlags.

2. A random salt value is computed.

3. The scopedPDU is encrypted using the salt and the secret privacy key for the user specified in msgUserName.

4. The salt is inserted into the msgPrivacyParameters.

5. Authenticate the packet as previously described.

6. The packet is sent.

Receiving an encrypted SNMPv3 packet:

1. The packet is received.

2. If the authentication flag is turned on in the msgFlags, then the packet must be authenticated as previously described and continue to step 3. If the authentication flag is turned off in the msgFlags, then decryption is skipped.

3. If the privacy flag is turned on in the msgFlags, continue with the decryption process at step 4. If the packet was not encrypted by the sender, then decryption is skipped.

4. Decrypt the scopedPDU using the salt specified in the msgSecurityParameters and the secret privacy key for the user specified in msgUserName.

5. Continue processing the packet.

User Table

Every agent maintains a User Table, which is used to store all the users that have access to the system via SNMP. Each user entry in the table contains the following information, all of which can be modified via SNMP operations on the USM MIB:

The User Table has a spin lock associated with it named usmUserSpinLock. A spin lock is an advisory lock, which is used to allow several SNMP managers to coordinate their attempts in modifying a MIB table. The concept is simple. Whenever a change is going to be made to the User Table on an agent, the value of the usmUserSpinLock must be retrieved via a GET command by the manager. Then the manager sends a SET command to the agent, which contains a PDU to set the usmUserSpinLock and whatever variables in the User Table that need to be modified. The value of the usmUserSpinLock in the SET command must be the value that was retrieved in the previous GET command. Once the agent receives the message containing the SET command, the usmUserSpinLock is immediately processed. If the current value of the usmUserSpinLock is not the same as the value specified in the SET command, the SET operation has failed and an error is returned. If the two values are the same, then the User Table variables specified in the PDU of the SET command are set. When the agent has finished processing the entire PDU, the usmUserSpinLock value is incremented by one. Thus, if the value of the usmUserSpinLock is different when it is being set, then the User Table has been modified since the initial retrieval of the usmUserSpinLock value.

Localized Keys

A localized key is a concept that allows the use of the same password for a user on many different agents. It would be very cumbersome to be forced to remember a different password for each agent in which the user exists. The localized key is computed using a one-way hash function (e.g., MD5 or SHA-1) against a secret password and the snmpEngineID of the agent where the user exists. This results in secret keys that, although use the same password, are completely different for each agent.

Changing Keys

The USM introduces the KeyChange type that describes a convention for using secret keys. The KeyChange definition provides a secure means of sending localized keys across networks, which allows users to change their keys. The following steps will occur when a user changes their key.

Manager:

1. The user enters in a new password.

2. The localized key is computed using the new password, and the snmpEngineID of the agent where the key is going to be changed.

3. A one-way function is used to produce a value from the old key.

4. This value is exclusively or'ed (XOR) with the new key.

5. The final KeyChange value is sent to the agent in a SET operation.

Agent: (after receiving the KeyChange SET operation)

1. The same one-way function that the manager used to produce a value from the old key is performed.

2. This value is exclusively or'ed (XOR) with the received KeyChange to produce the new key.

3. The new key for the user is set in the User Table.

Creating/Cloning Users

It is possible to create a new user in an agent's User Table. This is performed by cloning an existing user. All the data for the clone-from user is copied to the newly created entry for the new user. Once the new user entry has been created, it is suggested to immediately change the keys. Note that you can only create a new user by cloning from another existing user. This requires that the User Table for a particular agent must be initialized to contain the minimum set of users needed in your environment.

Using your SNMPv3 manager of choice, here is an example of how to create a new user from an existing user named foo and changing the secret keys. Note that the actual name of the new user being created is not shown here because the name is specified in the OID index of the variables which are being set. The User Table is indexed by the user name.

First, get the spin lock value and create the user. To ensure the new user entry cannot be immediately used, set the status to createAndWait.

sValue = GET (usmUserSpinLock)
SET((usmUserSpinLock = sValue),
    (usmUserCloneFrom = foo),
    (usmUserStatus = createAndWait))
Now, change the secret privacy key. Note you must know the secret privacy key for foo to compute the KeyChange. The privKeyChange value is computed using the privacy key of the clone-from user and the new secret key to be used for the new user. Make sure to use the spin lock. Also, the usmUserPublic variable can be written as part of the procedure for changing a user's secret key, and later read to determine whether the change of the secret was completed.
sValue = GET(usmUserSpinLock)
SET((usmUserSpinLock = sValue),
    (usmUserPrivKeyChange = privKeyChange),
    (usmUserPublic = randomValue))
if (randomValue != GET(usmUserPublic)) then try again
If the new user is never going to use encryption, then you can set the privProtocol to usmNoPrivProtocol and not bother with changing the privacy key.
sValue = GET(usmUserSpinLock)
SET((usmUserSpinLock = sValue),
    (usmUserPrivProtocol = usmNoPrivProtocol))
Next, change the secret authentication key. Note you must know the secret authentication key for foo to compute the KeyChange. The authKeyChange value is computed using the authentication key of the clone-from user and the new secret key to be used for the new user. Once again, make sure to use the spin lock.
sValue = GET(usmUserSpinLock)
SET((usmUserSpinLock = sValue),
    (usmUserAuthKeyChange = authKeyChange),
    (usmUserPublic = randomValue))
if (randomValue != GET(usmUserPublic)) then try again
If the new user is never going to use authentication, then you can set the authProtocol to usmNoAuthProtocol and not bother with changing the authentication key.
sValue = GET(usmUserSpinLock)
SET((usmUserSpinLock = sValue),
    (usmUserAuthProtocol = usmNoAuthProtocol))
Finally, activate this new user by setting the status to active.
sValue = GET(usmUserSpinLock)

SET((usmUserSpinLock = sValue),
    (usmUserStatus = active))
Conclusion

This overview of the USM should give you an understanding of what is involved in authenticating and encrypting/decrypting SNMPv3 packets. In addition, you can start to think about how you will configure the agents in your environment when you deploy SNMPv3 capable routers, switches, and servers. Next month, I will take a look at the VACM and show how it is used to administer access to MIB data.

References

SNMPv3: RFCs 2570, 2571, 2572, 2573, 2574, 2575

SNMP, SNMPv2, SNMPv3, and RMON 1 and 2 (Third Edition) by William Stallings, Addison-Wesley Publishing Company.

Understanding SNMP MIBs by David Perkins and Evan McGinnis, Prentice Hall PTR.

About the Author

Eric Davis is a Software Engineer in the networking division of Wind River Systems where he works on the TCP/IP stack of the VxWorks embedded OS. He lives in the SF Bay Area with his wife, Kathie, and dog, Maka. He can be reached at: [email protected].

Figure 1: SNMPv3 packet format

                  -------------------------
    /|\           | msgVersion            |
     |            |-----------------------|
     |            | msgID                 |
     |            |-----------------------|         USM Security Parameters
     |            | msgMaxSize            |
     |            |-----------------------|   ------------------------------
     |            | msgFlags              |  /| msgAuthoritativeEngineID   |
  scope of        |-----------------------| / |----------------------------|
authentication    | msgSecurityModel      |/  | msgAuthoritativeEngineBoots|
     |            |-----------------------|   |----------------------------|
     |            |                       |   | msgAuthoritativeEngineTime |
     |            | msgSecurityParameters |   |----------------------------|
     |            |                       |   | msgUserName                |
     |            |-----------------------|   |----------------------------|
     |     /|\    |                       |\  | msgAuthenticationParameters|
     |      |     |                       | \ |----------------------------|
     |      |     |                       |  \| msgPrivacyParameters       |
     |  scope of  | scopedPDU             |   ------------------------------
     | encryption |                       |
     |      |     |                       |
     |      |     |                       |
     |      |     |                       |
    \|/    \|/    |                       |
                  -------------------------

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.