11#if DETWS_ENABLE_SNMP_V3
19static inline void snmp_wipe(
void *p,
size_t n)
21 volatile uint8_t *v = (
volatile uint8_t *)p;
32static constexpr size_t SNMP_USM_PASS_MAX = 256;
34void snmp_usm_localize_key(
const char *password,
const uint8_t *engine_id,
size_t engine_id_len,
35 uint8_t key_out[SNMP_USM_KEY_LEN])
37 size_t pwlen = password ? strnlen(password, SNMP_USM_PASS_MAX) : 0;
40 memset(key_out, 0, SNMP_USM_KEY_LEN);
50 while (count < 1048576u)
52 for (
int i = 0; i < 64; i++)
54 block[i] = (uint8_t)password[pw_index];
55 pw_index = (pw_index + 1) % pwlen;
60 uint8_t ku[SNMP_USM_KEY_LEN];
70 snmp_wipe(ku,
sizeof(ku));
71 snmp_wipe(block,
sizeof(block));
80static const uint8_t kRcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
83static void aes128_key_schedule(
const uint8_t key[16], uint8_t rk[176])
86 for (
int i = 4; i < 44; i++)
89 memcpy(t, rk + (i - 1) * 4, 4);
93 t[0] = DET_AES_SBOX[t[1]];
94 t[1] = DET_AES_SBOX[t[2]];
95 t[2] = DET_AES_SBOX[t[3]];
96 t[3] = DET_AES_SBOX[tmp];
97 t[0] ^= kRcon[i / 4 - 1];
99 for (
int j = 0; j < 4; j++)
100 rk[i * 4 + j] = rk[(i - 4) * 4 + j] ^ t[j];
104static uint8_t xtime(uint8_t x)
106 return (uint8_t)((x << 1) ^ ((x >> 7) * 0x1b));
109static void aes128_encrypt_block(
const uint8_t rk[176],
const uint8_t in[16], uint8_t out[16])
112 for (
int i = 0; i < 16; i++)
113 s[i] = in[i] ^ rk[i];
115 for (
int round = 1; round <= 10; round++)
118 for (
int i = 0; i < 16; i++)
119 s[i] = DET_AES_SBOX[s[i]];
123 for (
int r = 0; r < 4; r++)
124 for (
int c = 0; c < 4; c++)
125 t[r + 4 * c] = s[r + 4 * ((c + r) % 4)];
131 for (
int c = 0; c < 4; c++)
133 uint8_t *col = s + 4 * c;
138 col[0] = (uint8_t)(xtime(a0) ^ (xtime(a1) ^ a1) ^ a2 ^ a3);
139 col[1] = (uint8_t)(a0 ^ xtime(a1) ^ (xtime(a2) ^ a2) ^ a3);
140 col[2] = (uint8_t)(a0 ^ a1 ^ xtime(a2) ^ (xtime(a3) ^ a3));
141 col[3] = (uint8_t)((xtime(a0) ^ a0) ^ a1 ^ a2 ^ xtime(a3));
146 for (
int i = 0; i < 16; i++)
147 s[i] ^= rk[round * 16 + i];
152void snmp_aes128_cfb(
const uint8_t key[16],
const uint8_t iv[16],
const uint8_t *in, uint8_t *out,
size_t len,
156 aes128_key_schedule(key, rk);
164 aes128_encrypt_block(rk, fb, ks);
165 size_t bl = len - off;
173 for (
size_t j = 0; j < bl; j++)
175 out[off + j] = in[off + j] ^ ks[j];
176 cipher[j] = out[off + j];
181 for (
size_t j = 0; j < bl; j++)
183 cipher[j] = in[off + j];
184 out[off + j] = in[off + j] ^ ks[j];
188 memcpy(fb, cipher, 16);
192 snmp_wipe(rk,
sizeof(rk));
193 snmp_wipe(ks,
sizeof(ks));
194 snmp_wipe(fb,
sizeof(fb));
The AES forward S-box (FIPS 197 Figure 7) - one shared copy.
USM cryptographic primitives for SNMPv3 (DETWS_ENABLE_SNMP_V3).
void ssh_sha256_init(SshSha256Ctx *ctx)
Initialize a streaming SHA-256 context.
void ssh_sha256_update(SshSha256Ctx *ctx, const uint8_t *data, size_t len)
Feed len bytes of data into the running hash.
void ssh_sha256_final(SshSha256Ctx *ctx, uint8_t digest[SSH_SHA256_DIGEST_LEN])
Finalize the hash and write the 32-byte digest.
SHA-256 (FIPS 180-4) - streaming context and one-shot API.
Streaming SHA-256 context.