1*5d5fbe79SDavid van Moolenbroek /**
2*5d5fbe79SDavid van Moolenbroek * @file
3*5d5fbe79SDavid van Moolenbroek * Additional SNMPv3 functionality RFC3414 and RFC3826.
4*5d5fbe79SDavid van Moolenbroek */
5*5d5fbe79SDavid van Moolenbroek
6*5d5fbe79SDavid van Moolenbroek /*
7*5d5fbe79SDavid van Moolenbroek * Copyright (c) 2016 Elias Oenal.
8*5d5fbe79SDavid van Moolenbroek * All rights reserved.
9*5d5fbe79SDavid van Moolenbroek *
10*5d5fbe79SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without modification,
11*5d5fbe79SDavid van Moolenbroek * are permitted provided that the following conditions are met:
12*5d5fbe79SDavid van Moolenbroek *
13*5d5fbe79SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright notice,
14*5d5fbe79SDavid van Moolenbroek * this list of conditions and the following disclaimer.
15*5d5fbe79SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright notice,
16*5d5fbe79SDavid van Moolenbroek * this list of conditions and the following disclaimer in the documentation
17*5d5fbe79SDavid van Moolenbroek * and/or other materials provided with the distribution.
18*5d5fbe79SDavid van Moolenbroek * 3. The name of the author may not be used to endorse or promote products
19*5d5fbe79SDavid van Moolenbroek * derived from this software without specific prior written permission.
20*5d5fbe79SDavid van Moolenbroek *
21*5d5fbe79SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22*5d5fbe79SDavid van Moolenbroek * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23*5d5fbe79SDavid van Moolenbroek * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24*5d5fbe79SDavid van Moolenbroek * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25*5d5fbe79SDavid van Moolenbroek * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26*5d5fbe79SDavid van Moolenbroek * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27*5d5fbe79SDavid van Moolenbroek * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*5d5fbe79SDavid van Moolenbroek * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29*5d5fbe79SDavid van Moolenbroek * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30*5d5fbe79SDavid van Moolenbroek * OF SUCH DAMAGE.
31*5d5fbe79SDavid van Moolenbroek *
32*5d5fbe79SDavid van Moolenbroek * Author: Elias Oenal <lwip@eliasoenal.com>
33*5d5fbe79SDavid van Moolenbroek */
34*5d5fbe79SDavid van Moolenbroek
35*5d5fbe79SDavid van Moolenbroek #include "snmpv3_priv.h"
36*5d5fbe79SDavid van Moolenbroek #include "lwip/apps/snmpv3.h"
37*5d5fbe79SDavid van Moolenbroek #include "lwip/sys.h"
38*5d5fbe79SDavid van Moolenbroek #include <string.h>
39*5d5fbe79SDavid van Moolenbroek
40*5d5fbe79SDavid van Moolenbroek #if LWIP_SNMP && LWIP_SNMP_V3
41*5d5fbe79SDavid van Moolenbroek
42*5d5fbe79SDavid van Moolenbroek #ifdef LWIP_SNMPV3_INCLUDE_ENGINE
43*5d5fbe79SDavid van Moolenbroek #include LWIP_SNMPV3_INCLUDE_ENGINE
44*5d5fbe79SDavid van Moolenbroek #endif
45*5d5fbe79SDavid van Moolenbroek
46*5d5fbe79SDavid van Moolenbroek #define SNMP_MAX_TIME_BOOT 2147483647UL
47*5d5fbe79SDavid van Moolenbroek
48*5d5fbe79SDavid van Moolenbroek /** Call this if engine has been changed. Has to reset boots, see below */
49*5d5fbe79SDavid van Moolenbroek void
snmpv3_engine_id_changed(void)50*5d5fbe79SDavid van Moolenbroek snmpv3_engine_id_changed(void)
51*5d5fbe79SDavid van Moolenbroek {
52*5d5fbe79SDavid van Moolenbroek snmpv3_set_engine_boots(0);
53*5d5fbe79SDavid van Moolenbroek }
54*5d5fbe79SDavid van Moolenbroek
55*5d5fbe79SDavid van Moolenbroek /** According to RFC3414 2.2.2.
56*5d5fbe79SDavid van Moolenbroek *
57*5d5fbe79SDavid van Moolenbroek * The number of times that the SNMP engine has
58*5d5fbe79SDavid van Moolenbroek * (re-)initialized itself since snmpEngineID
59*5d5fbe79SDavid van Moolenbroek * was last configured.
60*5d5fbe79SDavid van Moolenbroek */
61*5d5fbe79SDavid van Moolenbroek s32_t
snmpv3_get_engine_boots_internal(void)62*5d5fbe79SDavid van Moolenbroek snmpv3_get_engine_boots_internal(void)
63*5d5fbe79SDavid van Moolenbroek {
64*5d5fbe79SDavid van Moolenbroek if (snmpv3_get_engine_boots() == 0 ||
65*5d5fbe79SDavid van Moolenbroek snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT) {
66*5d5fbe79SDavid van Moolenbroek return snmpv3_get_engine_boots();
67*5d5fbe79SDavid van Moolenbroek }
68*5d5fbe79SDavid van Moolenbroek
69*5d5fbe79SDavid van Moolenbroek snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT);
70*5d5fbe79SDavid van Moolenbroek return snmpv3_get_engine_boots();
71*5d5fbe79SDavid van Moolenbroek }
72*5d5fbe79SDavid van Moolenbroek
73*5d5fbe79SDavid van Moolenbroek /** RFC3414 2.2.2.
74*5d5fbe79SDavid van Moolenbroek *
75*5d5fbe79SDavid van Moolenbroek * Once the timer reaches 2147483647 it gets reset to zero and the
76*5d5fbe79SDavid van Moolenbroek * engine boot ups get incremented.
77*5d5fbe79SDavid van Moolenbroek */
78*5d5fbe79SDavid van Moolenbroek s32_t
snmpv3_get_engine_time_internal(void)79*5d5fbe79SDavid van Moolenbroek snmpv3_get_engine_time_internal(void)
80*5d5fbe79SDavid van Moolenbroek {
81*5d5fbe79SDavid van Moolenbroek if (snmpv3_get_engine_time() >= SNMP_MAX_TIME_BOOT) {
82*5d5fbe79SDavid van Moolenbroek snmpv3_reset_engine_time();
83*5d5fbe79SDavid van Moolenbroek
84*5d5fbe79SDavid van Moolenbroek if (snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT - 1) {
85*5d5fbe79SDavid van Moolenbroek snmpv3_set_engine_boots(snmpv3_get_engine_boots() + 1);
86*5d5fbe79SDavid van Moolenbroek } else {
87*5d5fbe79SDavid van Moolenbroek snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT);
88*5d5fbe79SDavid van Moolenbroek }
89*5d5fbe79SDavid van Moolenbroek }
90*5d5fbe79SDavid van Moolenbroek
91*5d5fbe79SDavid van Moolenbroek return snmpv3_get_engine_time();
92*5d5fbe79SDavid van Moolenbroek }
93*5d5fbe79SDavid van Moolenbroek
94*5d5fbe79SDavid van Moolenbroek #if LWIP_SNMP_V3_CRYPTO
95*5d5fbe79SDavid van Moolenbroek
96*5d5fbe79SDavid van Moolenbroek /* This function ignores the byte order suggestion in RFC3414
97*5d5fbe79SDavid van Moolenbroek * since it simply doesn't influence the effectiveness of an IV.
98*5d5fbe79SDavid van Moolenbroek *
99*5d5fbe79SDavid van Moolenbroek * Implementing RFC3826 priv param algorithm if LWIP_RAND is available.
100*5d5fbe79SDavid van Moolenbroek *
101*5d5fbe79SDavid van Moolenbroek * @todo: This is a potential thread safety issue.
102*5d5fbe79SDavid van Moolenbroek */
103*5d5fbe79SDavid van Moolenbroek err_t
snmpv3_build_priv_param(u8_t * priv_param)104*5d5fbe79SDavid van Moolenbroek snmpv3_build_priv_param(u8_t* priv_param)
105*5d5fbe79SDavid van Moolenbroek {
106*5d5fbe79SDavid van Moolenbroek #ifdef LWIP_RAND /* Based on RFC3826 */
107*5d5fbe79SDavid van Moolenbroek static u8_t init;
108*5d5fbe79SDavid van Moolenbroek static u32_t priv1, priv2;
109*5d5fbe79SDavid van Moolenbroek
110*5d5fbe79SDavid van Moolenbroek /* Lazy initialisation */
111*5d5fbe79SDavid van Moolenbroek if (init == 0) {
112*5d5fbe79SDavid van Moolenbroek init = 1;
113*5d5fbe79SDavid van Moolenbroek priv1 = LWIP_RAND();
114*5d5fbe79SDavid van Moolenbroek priv2 = LWIP_RAND();
115*5d5fbe79SDavid van Moolenbroek }
116*5d5fbe79SDavid van Moolenbroek
117*5d5fbe79SDavid van Moolenbroek SMEMCPY(&priv_param[0], &priv1, sizeof(priv1));
118*5d5fbe79SDavid van Moolenbroek SMEMCPY(&priv_param[4], &priv2, sizeof(priv2));
119*5d5fbe79SDavid van Moolenbroek
120*5d5fbe79SDavid van Moolenbroek /* Emulate 64bit increment */
121*5d5fbe79SDavid van Moolenbroek priv1++;
122*5d5fbe79SDavid van Moolenbroek if (!priv1) { /* Overflow */
123*5d5fbe79SDavid van Moolenbroek priv2++;
124*5d5fbe79SDavid van Moolenbroek }
125*5d5fbe79SDavid van Moolenbroek #else /* Based on RFC3414 */
126*5d5fbe79SDavid van Moolenbroek static u32_t ctr;
127*5d5fbe79SDavid van Moolenbroek u32_t boots = snmpv3_get_engine_boots_internal();
128*5d5fbe79SDavid van Moolenbroek SMEMCPY(&priv_param[0], &boots, 4);
129*5d5fbe79SDavid van Moolenbroek SMEMCPY(&priv_param[4], &ctr, 4);
130*5d5fbe79SDavid van Moolenbroek ctr++;
131*5d5fbe79SDavid van Moolenbroek #endif
132*5d5fbe79SDavid van Moolenbroek return ERR_OK;
133*5d5fbe79SDavid van Moolenbroek }
134*5d5fbe79SDavid van Moolenbroek #endif /* LWIP_SNMP_V3_CRYPTO */
135*5d5fbe79SDavid van Moolenbroek
136*5d5fbe79SDavid van Moolenbroek #endif
137