1 /*
2 * Common code for the SSH format.
3 */
4
5 #include "arch.h"
6 #include "misc.h"
7 #include "common.h"
8 #include "ssh_common.h"
9
ssh_valid(char * ciphertext,struct fmt_main * self)10 int ssh_valid(char *ciphertext, struct fmt_main *self)
11 {
12 char *ctcopy, *keeptr, *p;
13 int len, cipher, extra;
14
15 if (strncmp(ciphertext, FORMAT_TAG, FORMAT_TAG_LEN))
16 return 0;
17 ctcopy = strdup(ciphertext);
18 keeptr = ctcopy;
19 ctcopy += FORMAT_TAG_LEN;
20 if ((p = strtokm(ctcopy, "$")) == NULL) /* cipher */
21 goto err;
22 if (!isdec(p))
23 goto err;
24 cipher = atoi(p);
25 if ((p = strtokm(NULL, "$")) == NULL) /* salt len */
26 goto err;
27 if (!isdec(p))
28 goto err;
29 len = atoi(p);
30 if (len > 16 || len < 8)
31 goto err;
32 if ((p = strtokm(NULL, "$")) == NULL) /* salt */
33 goto err;
34 if (hexlen(p, &extra) != len * 2 || extra)
35 goto err;
36 if ((p = strtokm(NULL, "$")) == NULL) /* ciphertext length */
37 goto err;
38 if (!isdec(p))
39 goto err;
40 len = atoi(p);
41 if ((p = strtokm(NULL, "$")) == NULL) /* ciphertext */
42 goto err;
43 if (hexlen(p, &extra) / 2 != len || extra)
44 goto err;
45 if (cipher == 2) {
46 if ((p = strtokm(NULL, "$")) == NULL) /* rounds */
47 goto err;
48 if (!isdec(p))
49 goto err;
50 if ((p = strtokm(NULL, "$")) == NULL) /* ciphertext_begin_offset */
51 goto err;
52 if (!isdec(p))
53 goto err;
54 if (atoi(p) + 16 > len)
55 goto err;
56 }
57
58 if (cipher < 0 || cipher > 5) {
59 fprintf(stderr, "[%s] cipher value of %d is not supported!\n",
60 self->params.label, cipher);
61 goto err;
62 }
63
64 MEM_FREE(keeptr);
65 return 1;
66
67 err:
68 MEM_FREE(keeptr);
69 return 0;
70 }
71
ssh_get_salt(char * ciphertext)72 void *ssh_get_salt(char *ciphertext)
73 {
74 char *ctcopy = strdup(ciphertext);
75 char *keeptr = ctcopy;
76 char *p;
77 int i;
78 static struct custom_salt cs;
79
80 memset(&cs, 0, sizeof(struct custom_salt));
81 cs.rounds = 1;
82 ctcopy += FORMAT_TAG_LEN; /* skip over "$sshng$" */
83 p = strtokm(ctcopy, "$");
84 cs.cipher = atoi(p);
85 p = strtokm(NULL, "$");
86 cs.sl = atoi(p);
87 p = strtokm(NULL, "$");
88 for (i = 0; i < cs.sl; i++)
89 cs.salt[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
90 + atoi16[ARCH_INDEX(p[i * 2 + 1])];
91 p = strtokm(NULL, "$");
92 cs.ctl = atoi(p);
93 p = strtokm(NULL, "$");
94 for (i = 0; i < cs.ctl; i++)
95 cs.ct[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
96 + atoi16[ARCH_INDEX(p[i * 2 + 1])];
97 if (cs.cipher == 2) {
98 p = strtokm(NULL, "$");
99 cs.rounds = atoi(p);
100 p = strtokm(NULL, "$");
101 cs.ciphertext_begin_offset = atoi(p);
102 }
103 MEM_FREE(keeptr);
104
105 return (void *)&cs;
106 }
107
ssh_iteration_count(void * salt)108 unsigned int ssh_iteration_count(void *salt)
109 {
110 struct custom_salt *cur_salt = salt;
111
112 switch (cur_salt->cipher) {
113 case 1:
114 case 3:
115 return 1; // generate 16 bytes of key + AES-128
116 case 4:
117 return 2; // generate 24 bytes of key + AES-192
118 case 5:
119 return 2; // generate 32 bytes of key + AES-256
120 case 0:
121 return 2; // generate 24 bytes of key + 3DES
122 default:
123 return cur_salt->rounds; // bcrypt KDF + AES-256 (ed25519)
124 }
125 }
126
ssh_kdf(void * salt)127 unsigned int ssh_kdf(void *salt)
128 {
129 struct custom_salt *cur_salt = salt;
130
131 switch (cur_salt->cipher) {
132 case 0:
133 return 1; // MD5 KDF + 3DES
134 case 2:
135 return 2; // bcrypt-pbkdf
136 default:
137 return 0; // MD5 KDF + AES
138 }
139 }
140