Re: snmp agent inform w/AES privacy not working
Raimo Niskanen <[email protected]> Wed, 6 Aug 2014 11:51:33 +0200
| Newsgroups | gmane.comp.lang.erlang.bugs,gmane.comp.lang.erlang.patches |
|---|---|
| Message-ID | <[email protected]> |
Sorry about the looong delay but I have just created a ticket for this, now awaiting to be prioritized... / Raimo On Tue, Feb 25, 2014 at 11:56:32AM -0600, Daniel Goertzen wrote: > The SNMP agent AES initialization vector calculation is definitely wrong. > The IV is composed from the authoritative engine boots, engine time, and a > random locally generated number. The agent is currently always using the > *local* engine to get engine boots and engine time, which happens to be > correct for GET, SET, and TRAP, but is wrong for INFORM. > > The attached patch fixes it. When composing a packet for transmission, the > existing code collects the correct engine parameters, so this patch just > uses those for the AES IV instead of going off and getting the wrong local > engine params. The patch looks bigger than it really is because the order > of packet composition had to be changed slightly. > > With this patch applied, I am able to send AES encrypted informs. AES > encrypted traps also continued to work. > > Cheers, > Dan. > > > On Mon, Feb 24, 2014 at 4:57 PM, Daniel Goertzen > <[email protected]>wrote: > > > I am struggling to get SNMP informs with AES privacy working. I have no > > problems with DES privacy on informs. > > > > In snmpa_usm.erl I see that the *local engine* boots and time is passed to > > snmp_usm:aes_encrypt() which forms part of the IV.... > > > > > > > > However RFC 3826 states that the *authoritative* engine boots and time > > should be used, and in the case of informs the authoritative engine is the > > inform target engine, not the local engine.... > > > > [from RFC 3826] > > > > 3.1.2.1. AES Encryption Key and IV > > > > The first 128 bits of the localized key Kul are used as the AES > > encryption key. The 128-bit IV is obtained as the concatenation of > > the authoritative SNMP engine's 32-bit snmpEngineBoots, the SNMP > > engine's 32-bit snmpEngineTime, and a local 64-bit integer. The 64- > > bit integer is initialized to a pseudo-random value at boot time. > > > > > > > > Could this be why AES privacy is not working for informs? > > > > Dan. > > > diff --git a/lib/snmp/src/agent/snmpa_usm.erl b/lib/snmp/src/agent/snmpa_usm.erl > index 719ea4e..0c3528a 100644 > --- a/lib/snmp/src/agent/snmpa_usm.erl > +++ b/lib/snmp/src/agent/snmpa_usm.erl > @@ -474,6 +474,23 @@ generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel, > _ -> % 3.1.1a > SecData > end, > + %% 3.1.6 > + SnmpEngineID = LocalEngineID, > + ?vtrace("generate_outgoing_msg -> SnmpEngineID: ~p [3.1.6]", > + [SnmpEngineID]), > + {MsgAuthEngineBoots, MsgAuthEngineTime} = > + case snmp_misc:is_auth(SecLevel) of > + false when SecData =:= [] -> % not a response > + {0, 0}; > + false when UserName =:= "" -> % reply (report) to discovery step 1 > + {0, 0}; > + true when SecEngineID =/= SnmpEngineID -> > + {get_engine_boots(SecEngineID), > + get_engine_time(SecEngineID)}; > + _ -> > + {get_local_engine_boots(SnmpEngineID), > + get_local_engine_time(SnmpEngineID)} > + end, > %% 3.1.4 > ?vtrace("generate_outgoing_msg -> [3.1.4]" > "~n UserName: ~p" > @@ -482,24 +499,7 @@ generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel, > [UserName, AuthProtocol, PrivProtocol]), > ScopedPduBytes = Message#message.data, > {ScopedPduData, MsgPrivParams} = > - encrypt(ScopedPduBytes, PrivProtocol, PrivKey, SecLevel), > - SnmpEngineID = LocalEngineID, > - ?vtrace("generate_outgoing_msg -> SnmpEngineID: ~p [3.1.6]", > - [SnmpEngineID]), > - %% 3.1.6 > - {MsgAuthEngineBoots, MsgAuthEngineTime} = > - case snmp_misc:is_auth(SecLevel) of > - false when SecData =:= [] -> % not a response > - {0, 0}; > - false when UserName =:= "" -> % reply (report) to discovery step 1 > - {0, 0}; > - true when SecEngineID =/= SnmpEngineID -> > - {get_engine_boots(SecEngineID), > - get_engine_time(SecEngineID)}; > - _ -> > - {get_local_engine_boots(SnmpEngineID), > - get_local_engine_time(SnmpEngineID)} > - end, > + encrypt(ScopedPduBytes, PrivProtocol, PrivKey, SecLevel, MsgAuthEngineBoots, MsgAuthEngineTime), > %% 3.1.5 - 3.1.7 > ?vtrace("generate_outgoing_msg -> [3.1.5 - 3.1.7]",[]), > UsmSecParams = > @@ -560,12 +560,14 @@ generate_discovery_msg(Message, > end > end, > ScopedPduBytes = Message#message.data, > + Boots = 0, > + Time = 0, > {ScopedPduData, MsgPrivParams} = > - encrypt(ScopedPduBytes, PrivProtocol, PrivKey, SecLevel), > + encrypt(ScopedPduBytes, PrivProtocol, PrivKey, SecLevel, Boots, Time), > UsmSecParams = > #usmSecurityParameters{msgAuthoritativeEngineID = SecEngineID, > - msgAuthoritativeEngineBoots = 0, % Boots, > - msgAuthoritativeEngineTime = 0, % Time, > + msgAuthoritativeEngineBoots = Boots, > + msgAuthoritativeEngineTime = Time, > msgUserName = UserName, > msgPrivacyParameters = MsgPrivParams}, > Message2 = Message#message{data = ScopedPduData}, > @@ -574,14 +576,14 @@ generate_discovery_msg(Message, > > > %% Ret: {ScopedPDU, MsgPrivParams} - both are already encoded as OCTET STRINGs > -encrypt(Data, PrivProtocol, PrivKey, SecLevel) -> > +encrypt(Data, PrivProtocol, PrivKey, SecLevel, AuthEngineBoots, AuthEngineTime) -> > case snmp_misc:is_priv(SecLevel) of > false -> % 3.1.4b > ?vtrace("encrypt -> 3.1.4b",[]), > {Data, []}; > true -> % 3.1.4a > ?vtrace("encrypt -> 3.1.4a",[]), > - case (catch try_encrypt(PrivProtocol, PrivKey, Data)) of > + case (catch try_encrypt(PrivProtocol, PrivKey, Data, AuthEngineBoots, AuthEngineTime)) of > {ok, ScopedPduData, MsgPrivParams} -> > ?vtrace("encrypt -> encrypted - now encode tag",[]), > {snmp_pdus:enc_oct_str_tag(ScopedPduData), MsgPrivParams}; > @@ -596,12 +598,12 @@ encrypt(Data, PrivProtocol, PrivKey, SecLevel) -> > end > end. > > -try_encrypt(?usmNoPrivProtocol, _PrivKey, _Data) -> % 3.1.2 > +try_encrypt(?usmNoPrivProtocol, _PrivKey, _Data, _AuthEngineBoots, _AuthEngineTime) -> % 3.1.2 > error(unsupportedSecurityLevel); > -try_encrypt(?usmDESPrivProtocol, PrivKey, Data) -> > +try_encrypt(?usmDESPrivProtocol, PrivKey, Data, _AuthEngineBoots, _AuthEngineTime) -> > des_encrypt(PrivKey, Data); > -try_encrypt(?usmAesCfb128Protocol, PrivKey, Data) -> > - aes_encrypt(PrivKey, Data). > +try_encrypt(?usmAesCfb128Protocol, PrivKey, Data, AuthEngineBoots, AuthEngineTime) -> > + aes_encrypt(PrivKey, Data, AuthEngineBoots, AuthEngineTime). > > > authenticate_outgoing(Message, UsmSecParams, > @@ -654,10 +656,8 @@ get_des_salt() -> > EngineBoots = snmp_framework_mib:get_engine_boots(), > [?i32(EngineBoots), ?i32(SaltInt)]. > > -aes_encrypt(PrivKey, Data) -> > - EngineBoots = snmp_framework_mib:get_engine_boots(), > - EngineTime = snmp_framework_mib:get_engine_time(), > - snmp_usm:aes_encrypt(PrivKey, Data, fun get_aes_salt/0, > +aes_encrypt(PrivKey, Data, EngineBoots, EngineTime) -> > + snmp_usm:aes_encrypt(PrivKey, Data, fun get_aes_salt/0, > EngineBoots, EngineTime). > > aes_decrypt(PrivKey, UsmSecParams, EncData) -> > _______________________________________________ > erlang-bugs mailing list > [email protected] > http://erlang.org/mailman/listinfo/erlang-bugs -- / Raimo Niskanen, Erlang/OTP, Ericsson AB _______________________________________________ erlang-bugs mailing list [email protected] http://erlang.org/mailman/listinfo/erlang-bugs