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