1 /*
2 * Common code for the Ansible Vault format.
3 */
4
5 #include "arch.h"
6 #include "misc.h"
7 #include "common.h"
8 #include "ansible_common.h"
9
10 struct fmt_tests ansible_tests[] = {
11 {"$ansible$0*0*f623a48ba49f7abf7c1920bc1e2ab2607cda2b5786da2560b8178a6095e5dfd2*ab55de42e4f131f109f1a086f2e8e22f*6767c60857ce1d7aa20226d76ec1abf77837c623bb7e879147ab888ef15a0dbb", "openwall"},
12 {"$ansible$0*0*45252709c61203511abbfdab0a8b498cb3e6259be5211e5b33ccc2fe12211d3f*0c52b98fc5aed891f99e3bcd3c6f250a*8e2d7558cd75b293ad8f3e27b774704279c019d89ba4743b591a3b14883c0851", "åbc"},
13 {NULL}
14 };
15
ansible_common_valid(char * ciphertext,struct fmt_main * self)16 int ansible_common_valid(char *ciphertext, struct fmt_main *self)
17 {
18 char *ctcopy, *keeptr, *p;
19 int value, extra;
20
21 if (strncmp(ciphertext, FORMAT_TAG, TAG_LENGTH) != 0)
22 return 0;
23
24 ctcopy = strdup(ciphertext);
25 keeptr = ctcopy;
26
27 ctcopy += TAG_LENGTH;
28 if ((p = strtokm(ctcopy, "*")) == NULL) // version, for future purposes
29 goto err;
30 if (!isdec(p))
31 goto err;
32 value = atoi(p);
33 if (value != 0)
34 goto err;
35 if ((p = strtokm(NULL, "*")) == NULL) // cipher (fixed for now)
36 goto err;
37 if (!isdec(p))
38 goto err;
39 if (atoi(p) != 0)
40 goto err;
41 if ((p = strtokm(NULL, "*")) == NULL) // salt
42 goto err;
43 if (hexlenl(p, &extra) != SALTLEN * 2 || extra)
44 goto err;
45 if ((p = strtokm(NULL, "*")) == NULL) // ciphertext
46 goto err;
47 if (hexlenl(p, &extra) >= BLOBLEN * 2 || extra)
48 goto err;
49 if ((p = strtokm(NULL, "*")) == NULL) // checksum
50 goto err;
51 if (hexlenl(p, &extra) != 32 * 2 || extra)
52 goto err;
53
54 MEM_FREE(keeptr);
55 return 1;
56
57 err:
58 MEM_FREE(keeptr);
59 return 0;
60 }
61
ansible_common_get_salt(char * ciphertext)62 void *ansible_common_get_salt(char *ciphertext)
63 {
64 char *ctcopy = strdup(ciphertext);
65 char *keeptr = ctcopy;
66 int i;
67 char *p;
68 static struct custom_salt *cs;
69
70 cs = mem_calloc_tiny(sizeof(struct custom_salt), sizeof(uint64_t));
71
72 ctcopy += TAG_LENGTH;
73 p = strtokm(ctcopy, "*");
74 p = strtokm(NULL, "*");
75 cs->iterations = 10000; // fixed
76 cs->salt_length = SALTLEN;
77 p = strtokm(NULL, "*");
78 for (i = 0; i < cs->salt_length; i++)
79 cs->salt[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
80 + atoi16[ARCH_INDEX(p[i * 2 + 1])];
81 p = strtokm(NULL, "*");
82 cs->bloblen = strlen(p) / 2;
83 for (i = 0; i < cs->bloblen; i++)
84 cs->blob[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
85 + atoi16[ARCH_INDEX(p[i * 2 + 1])];
86 p = strtokm(NULL, "*");
87 for (i = 0; i < 32; i++)
88 cs->checksum[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
89 + atoi16[ARCH_INDEX(p[i * 2 + 1])];
90 MEM_FREE(keeptr);
91
92 return (void *)cs;
93 }
94
ansible_common_get_binary(char * ciphertext)95 void *ansible_common_get_binary(char *ciphertext)
96 {
97 static union {
98 unsigned char c[BINARY_SIZE];
99 uint32_t dummy;
100 } buf;
101 unsigned char *out = buf.c;
102 char *p;
103 int i;
104
105 memset(buf.c, 0, BINARY_SIZE);
106 p = strrchr(ciphertext, '*') + 1;
107 for (i = 0; i < BINARY_SIZE_CMP; i++) {
108 out[i] = (atoi16[ARCH_INDEX(*p)] << 4) | atoi16[ARCH_INDEX(p[1])];
109 p += 2;
110 }
111
112 return out;
113 }
114
ansible_common_iteration_count(void * salt)115 unsigned int ansible_common_iteration_count(void *salt)
116 {
117 struct custom_salt *cs = salt;
118
119 return (unsigned int) cs->iterations;
120 }
121