Skip to content

Commit 80a3952

Browse files
committed
Add support for 'Cisco-ISE Hashed Password (SHA256)'
1 parent 7a62a41 commit 80a3952

File tree

1 file changed

+254
-0
lines changed

1 file changed

+254
-0
lines changed

src/cisco_ise_sha256_fmt_plug.c

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
/*
2+
* Cisco-ISE Hashed Password (SHA256)
3+
*
4+
* This software is Copyright (c) 2026 Dhiru Kholia and it is hereby released
5+
* to the general public under the following terms:
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted.
9+
*
10+
* Algorithm:
11+
* digest = SHA256(salt || password)
12+
* repeat 128 times: digest = SHA256(digest)
13+
*
14+
* Hash format: 128 hex chars, where first 64 hex is digest and last 64 hex is salt.
15+
*/
16+
17+
#if FMT_EXTERNS_H
18+
extern struct fmt_main fmt_cisco_ise_sha256;
19+
#elif FMT_REGISTERS_H
20+
john_register_one(&fmt_cisco_ise_sha256);
21+
#else
22+
23+
#include <string.h>
24+
25+
#ifdef _OPENMP
26+
#include <omp.h>
27+
#endif
28+
29+
#define OMP_SCALE 256
30+
31+
#include "common.h"
32+
#include "formats.h"
33+
#include "misc.h"
34+
#include "sha2.h"
35+
36+
#define FORMAT_LABEL "Cisco-ISE-SHA256"
37+
#define FORMAT_NAME "Cisco ISE"
38+
#define ALGORITHM_NAME "SHA256 32/" ARCH_BITS_STR
39+
#define BENCHMARK_COMMENT ""
40+
#define BENCHMARK_LENGTH 7
41+
#define PLAINTEXT_LENGTH MAX_PLAINTEXT_LENGTH
42+
#define CIPHERTEXT_LENGTH 128
43+
#define BINARY_SIZE 32
44+
#define BINARY_ALIGN 4
45+
#define SALT_SIZE 32
46+
#define SALT_ALIGN 4
47+
#define MIN_KEYS_PER_CRYPT 1
48+
#define MAX_KEYS_PER_CRYPT 16
49+
50+
#define ISE_ITERATIONS 128
51+
52+
static struct fmt_tests tests[] = {
53+
{"465865d4226c4d9696e601f2c99b25ae2c194ec01806bafc93933331acfc1a60e8bdcca8be9fa245a5fa16029bb52480915746f47d1c539d01da7ec6f37468d1", "hashcat"},
54+
{"a6c9702dae629b71383eb2819f00464985c2188db7ff83a9cb5137eb6ee975d500112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", "OpenAI2026!"}, // Synthetic test vector
55+
{NULL}
56+
};
57+
58+
static SHA256_CTX ctx_salt;
59+
60+
static char (*saved_key)[PLAINTEXT_LENGTH + 1];
61+
static int (*saved_len);
62+
static uint32_t (*crypt_out)[BINARY_SIZE / sizeof(uint32_t)];
63+
64+
static void init(struct fmt_main *self)
65+
{
66+
omp_autotune(self, OMP_SCALE);
67+
68+
saved_key = mem_calloc(self->params.max_keys_per_crypt,
69+
sizeof(*saved_key));
70+
saved_len = mem_calloc(self->params.max_keys_per_crypt,
71+
sizeof(*saved_len));
72+
crypt_out = mem_calloc(self->params.max_keys_per_crypt,
73+
sizeof(*crypt_out));
74+
}
75+
76+
static void done(void)
77+
{
78+
MEM_FREE(crypt_out);
79+
MEM_FREE(saved_len);
80+
MEM_FREE(saved_key);
81+
}
82+
83+
static int valid(char *ciphertext, struct fmt_main *self)
84+
{
85+
if (strlen(ciphertext) != CIPHERTEXT_LENGTH)
86+
return 0;
87+
if (!ishex(ciphertext))
88+
return 0;
89+
return 1;
90+
}
91+
92+
static void *get_salt(char *ciphertext)
93+
{
94+
static union {
95+
unsigned char b[SALT_SIZE];
96+
uint32_t dummy;
97+
} out;
98+
const char *p = ciphertext + (CIPHERTEXT_LENGTH - (SALT_SIZE * 2));
99+
int i;
100+
101+
for (i = 0; i < SALT_SIZE; i++) {
102+
out.b[i] = (atoi16[ARCH_INDEX(p[0])] << 4) | atoi16[ARCH_INDEX(p[1])];
103+
p += 2;
104+
}
105+
106+
return out.b;
107+
}
108+
109+
static void set_salt(void *salt)
110+
{
111+
SHA256_Init(&ctx_salt);
112+
SHA256_Update(&ctx_salt, salt, SALT_SIZE);
113+
}
114+
115+
static void set_key(char *key, int index)
116+
{
117+
saved_len[index] = strnzcpyn(saved_key[index], key, sizeof(*saved_key));
118+
}
119+
120+
static char *get_key(int index)
121+
{
122+
return saved_key[index];
123+
}
124+
125+
static void *get_binary(char *ciphertext)
126+
{
127+
static union {
128+
unsigned char b[BINARY_SIZE];
129+
uint32_t dummy;
130+
} out;
131+
const char *p = ciphertext;
132+
int i;
133+
134+
for (i = 0; i < BINARY_SIZE; i++) {
135+
out.b[i] = (atoi16[ARCH_INDEX(p[0])] << 4) | atoi16[ARCH_INDEX(p[1])];
136+
p += 2;
137+
}
138+
139+
return out.b;
140+
}
141+
142+
static int cmp_all(void *binary, int count)
143+
{
144+
uint32_t b0 = *(uint32_t *)binary;
145+
int i;
146+
147+
for (i = 0; i < count; i++) {
148+
if (b0 != crypt_out[i][0])
149+
continue;
150+
if (!memcmp(binary, crypt_out[i], BINARY_SIZE))
151+
return 1;
152+
}
153+
return 0;
154+
}
155+
156+
static int cmp_one(void *binary, int index)
157+
{
158+
return !memcmp(binary, crypt_out[index], BINARY_SIZE);
159+
}
160+
161+
static int cmp_exact(char *source, int index)
162+
{
163+
return 1;
164+
}
165+
166+
static int crypt_all(int *pcount, struct db_salt *salt)
167+
{
168+
int count = *pcount;
169+
int i;
170+
171+
#ifdef _OPENMP
172+
#pragma omp parallel for default(none) private(i) shared(count, saved_key, saved_len, crypt_out, ctx_salt)
173+
#endif
174+
for (i = 0; i < count; i++) {
175+
SHA256_CTX ctx;
176+
unsigned char digest[BINARY_SIZE];
177+
int r;
178+
179+
memcpy(&ctx, &ctx_salt, sizeof(ctx));
180+
SHA256_Update(&ctx, saved_key[i], saved_len[i]);
181+
SHA256_Final(digest, &ctx);
182+
183+
for (r = 0; r < ISE_ITERATIONS; r++) {
184+
SHA256_Init(&ctx);
185+
SHA256_Update(&ctx, digest, BINARY_SIZE);
186+
SHA256_Final(digest, &ctx);
187+
}
188+
189+
memcpy(crypt_out[i], digest, BINARY_SIZE);
190+
}
191+
192+
return count;
193+
}
194+
195+
#define COMMON_GET_HASH_VAR crypt_out
196+
#include "common-get-hash.h"
197+
198+
struct fmt_main fmt_cisco_ise_sha256 = {
199+
{
200+
FORMAT_LABEL,
201+
FORMAT_NAME,
202+
ALGORITHM_NAME,
203+
BENCHMARK_COMMENT,
204+
BENCHMARK_LENGTH,
205+
0,
206+
PLAINTEXT_LENGTH,
207+
BINARY_SIZE,
208+
BINARY_ALIGN,
209+
SALT_SIZE,
210+
SALT_ALIGN,
211+
MIN_KEYS_PER_CRYPT,
212+
MAX_KEYS_PER_CRYPT,
213+
FMT_CASE | FMT_8_BIT | FMT_OMP,
214+
{ NULL },
215+
{ NULL },
216+
tests
217+
}, {
218+
init,
219+
done,
220+
fmt_default_reset,
221+
fmt_default_prepare,
222+
valid,
223+
fmt_default_split,
224+
get_binary,
225+
get_salt,
226+
{ NULL },
227+
fmt_default_source,
228+
{
229+
fmt_default_binary_hash_0,
230+
fmt_default_binary_hash_1,
231+
fmt_default_binary_hash_2,
232+
fmt_default_binary_hash_3,
233+
fmt_default_binary_hash_4,
234+
fmt_default_binary_hash_5,
235+
fmt_default_binary_hash_6
236+
},
237+
fmt_default_salt_hash,
238+
NULL,
239+
set_salt,
240+
set_key,
241+
get_key,
242+
fmt_default_clear_keys,
243+
crypt_all,
244+
{
245+
#define COMMON_GET_HASH_LINK
246+
#include "common-get-hash.h"
247+
},
248+
cmp_all,
249+
cmp_one,
250+
cmp_exact
251+
}
252+
};
253+
254+
#endif

0 commit comments

Comments
 (0)