25#define PC_SNMP_USM_PASS_MAX 256
27void pc_snmp_usm_localize_key(
const char *password,
const uint8_t *engine_id,
size_t engine_id_len,
28 uint8_t key_out[SNMP_USM_KEY_LEN])
30 size_t pwlen = password ? strnlen(password, PC_SNMP_USM_PASS_MAX) : 0;
33 memset(key_out, 0, SNMP_USM_KEY_LEN);
43 while (count < 1048576u)
45 for (
int i = 0; i < 64; i++)
47 block[i] = (uint8_t)password[pw_index];
48 pw_index = (pw_index + 1) % pwlen;
53 uint8_t ku[SNMP_USM_KEY_LEN];
63 pc_secure_wipe(ku,
sizeof(ku));
64 pc_secure_wipe(block,
sizeof(block));
71static const uint8_t kRcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
74static void aes128_key_schedule(
const uint8_t key[16], uint8_t rk[176])
77 for (
int i = 4; i < 44; i++)
80 memcpy(t, rk + (i - 1) * 4, 4);
84 t[0] = PC_AES_SBOX[t[1]];
85 t[1] = PC_AES_SBOX[t[2]];
86 t[2] = PC_AES_SBOX[t[3]];
87 t[3] = PC_AES_SBOX[tmp];
88 t[0] ^= kRcon[i / 4 - 1];
90 for (
int j = 0; j < 4; j++)
92 rk[i * 4 + j] = rk[(i - 4) * 4 + j] ^ t[j];
97static uint8_t xtime(uint8_t x)
99 return (uint8_t)((x << 1) ^ ((x >> 7) * 0x1b));
102static void aes128_encrypt_block(
const uint8_t rk[176],
const uint8_t in[16], uint8_t out[16])
105 for (
int i = 0; i < 16; i++)
107 s[i] = in[i] ^ rk[i];
110 for (
int round = 1; round <= 10; round++)
113 for (
int i = 0; i < 16; i++)
115 s[i] = PC_AES_SBOX[s[i]];
120 for (
int r = 0; r < 4; r++)
122 for (
int c = 0; c < 4; c++)
124 t[r + 4 * c] = s[r + 4 * ((c + r) % 4)];
132 for (
int c = 0; c < 4; c++)
134 uint8_t *col = s + 4 * c;
139 col[0] = (uint8_t)(xtime(a0) ^ (xtime(a1) ^ a1) ^ a2 ^ a3);
140 col[1] = (uint8_t)(a0 ^ xtime(a1) ^ (xtime(a2) ^ a2) ^ a3);
141 col[2] = (uint8_t)(a0 ^ a1 ^ xtime(a2) ^ (xtime(a3) ^ a3));
142 col[3] = (uint8_t)((xtime(a0) ^ a0) ^ a1 ^ a2 ^ xtime(a3));
147 for (
int i = 0; i < 16; i++)
149 s[i] ^= rk[round * 16 + i];
155void pc_snmp_aes128_cfb(
const uint8_t key[16],
const uint8_t iv[16],
const uint8_t *in, uint8_t *out,
size_t len,
159 aes128_key_schedule(key, rk);
167 aes128_encrypt_block(rk, fb, ks);
168 size_t bl = len - off;
178 for (
size_t j = 0; j < bl; j++)
180 out[off + j] = in[off + j] ^ ks[j];
181 cipher[j] = out[off + j];
186 for (
size_t j = 0; j < bl; j++)
188 cipher[j] = in[off + j];
189 out[off + j] = in[off + j] ^ ks[j];
194 memcpy(fb, cipher, 16);
199 pc_secure_wipe(rk,
sizeof(rk));
200 pc_secure_wipe(ks,
sizeof(ks));
201 pc_secure_wipe(fb,
sizeof(fb));
The AES forward S-box (FIPS 197 Figure 7) - one shared copy.
Constant-time comparison for secret-dependent checks.
Secure pool accessor - borrows that hold key material.
PC_CRYPTO_HOT void pc_sha256_init(pc_sha256_ctx *ctx)
Initialize a streaming SHA-256 context (ctx must not be NULL).
void pc_sha256_final(pc_sha256_ctx *ctx, uint8_t digest[PC_SHA256_DIGEST_LEN])
Finalize the hash and write the 32-byte digest. The context is undefined afterwards; call init() agai...
void pc_sha256_update(pc_sha256_ctx *ctx, const uint8_t *data, size_t len)
Feed len bytes of data into the running hash.
SHA-256 (FIPS 180-4) - streaming context and one-shot API.
Streaming SHA-256 context.