1 /*
2  * securid.c - SecurID token handling
3  *
4  * Copyright 2012 Kevin Cernekee <cernekee@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "config.h"
22 
23 #include <ctype.h>
24 #include <fcntl.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
30 #include <sys/stat.h>
31 #include <sys/time.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 
35 #include "securid.h"
36 #include "sdtid.h"
37 
38 struct v3_token {
39 	uint8_t			version;
40 	uint8_t			password_locked;
41 	uint8_t			devid_locked;
42 	uint8_t			nonce_devid_hash[SHA256_HASH_SIZE];
43 	uint8_t			nonce_devid_pass_hash[SHA256_HASH_SIZE];
44 	uint8_t			nonce[V3_NONCE_BYTES];
45 	uint8_t			enc_payload[0xb0];
46 	uint8_t			mac[SHA256_HASH_SIZE];
47 };
48 
49 #define V3_ADDPIN_OFF		0x1f
50 #define V3_ADDPIN_ON		0x21
51 
52 struct v3_payload {
53 	char			serial[16];
54 	uint8_t			dec_seed[AES_KEY_SIZE];
55 	uint8_t			unk0[2];
56 	uint8_t			mode;
57 	uint8_t			digits;
58 	uint8_t			addpin;
59 	uint8_t			interval;
60 	uint8_t			res0[2];
61 	uint8_t			birth_date[5];
62 	uint8_t			res1[3];
63 	uint8_t			exp_date[5];
64 	uint8_t			res2[0x6b];
65 	uint8_t			padding[0x10];
66 };
67 
68 /********************************************************************
69  * Utility and crypto functions
70  ********************************************************************/
71 
hex2nibble(char in)72 static uint8_t hex2nibble(char in)
73 {
74 	uint8_t ret = in - '0';
75 	return (ret <= 9) ? ret : (10 + toupper(in) - 'A');
76 }
77 
hex2byte(const char * in)78 static uint8_t hex2byte(const char *in)
79 {
80 	return (hex2nibble(in[0]) << 4) | hex2nibble(in[1]);
81 }
82 
securid_rand(void * out,int len,int paranoid)83 int securid_rand(void *out, int len, int paranoid)
84 {
85 	int fd;
86 	char *p = out;
87 
88 	/*
89 	 * Use /dev/random for long lived key material but not for
90 	 * test purposes.  This can block for a long time if entropy
91 	 * is limited.
92 	 */
93 	fd = open(paranoid ? "/dev/random" : "/dev/urandom", O_RDONLY);
94 	if (fd < 0)
95 		return ERR_GENERAL;
96 
97 	while (len) {
98 		ssize_t ret = read(fd, p, len);
99 		if (ret < 0) {
100 			close(fd);
101 			return ERR_GENERAL;
102 		}
103 		p += ret;
104 		len -= ret;
105 	}
106 	close(fd);
107 	return ERR_NONE;
108 }
109 
encrypt_then_xor(const uint8_t * key,uint8_t * work,uint8_t * enc)110 static void encrypt_then_xor(const uint8_t *key, uint8_t *work, uint8_t *enc)
111 {
112 	int i;
113 
114 	stc_aes128_ecb_encrypt(key, work, enc);
115 	for (i = 0; i < AES_BLOCK_SIZE; i++)
116 		work[i] ^= enc[i];
117 }
118 
securid_mac(const uint8_t * in,int in_len,uint8_t * out)119 static void securid_mac(const uint8_t *in, int in_len, uint8_t *out)
120 {
121 	int i, odd = 0;
122 	const int incr = AES_KEY_SIZE;
123 	uint8_t work[incr], enc[incr], pad[incr], zero[incr], lastblk[incr], *p;
124 
125 	memset(zero, 0, incr);
126 	memset(pad, 0, incr);
127 	memset(lastblk, 0, incr);
128 	memset(work, 0xff, incr);
129 
130 	/* padding */
131 	p = &pad[incr - 1];
132 	for (i = in_len * 8; i > 0; i >>= 8)
133 		*(p--) = (uint8_t)i;
134 
135 	/* handle the bulk of the input data here */
136 	for (; in_len > incr; in_len -= incr, in += incr, odd = !odd)
137 		encrypt_then_xor(in, work, enc);
138 
139 	/* final 0-16 bytes of input data */
140 	memcpy(lastblk, in, in_len);
141 	encrypt_then_xor(lastblk, work, enc);
142 
143 	/* hash an extra block of zeroes, for certain input lengths */
144 	if (odd)
145 		encrypt_then_xor(zero, work, enc);
146 
147 	/* always hash the padding */
148 	encrypt_then_xor(pad, work, enc);
149 
150 	/* run hash over current hash value, then return */
151 	memcpy(out, work, incr);
152 	encrypt_then_xor(work, out, enc);
153 }
154 
securid_shortmac(const uint8_t * in,int in_len)155 static uint16_t securid_shortmac(const uint8_t *in, int in_len)
156 {
157 	uint8_t hash[AES_BLOCK_SIZE];
158 
159 	securid_mac(in, in_len, hash);
160 	return (hash[0] << 7) | (hash[1] >> 1);
161 }
162 
sha256_hmac(const uint8_t * key,int key_len,const uint8_t * msg,int msg_len,uint8_t * out)163 static void sha256_hmac(const uint8_t *key, int key_len,
164 			const uint8_t *msg, int msg_len, uint8_t *out)
165 {
166 	uint8_t tmp_key[SHA256_HASH_SIZE], o_key_pad[SHA256_BLOCK_SIZE],
167 		i_key_pad[SHA256_BLOCK_SIZE], inner_hash[SHA256_BLOCK_SIZE];
168 	int i;
169 
170 	if (key_len > SHA256_BLOCK_SIZE) {
171 		stc_sha256_hash(tmp_key, key, key_len, NULL);
172 		key = tmp_key;
173 		key_len = SHA256_HASH_SIZE;
174 	}
175 
176 	memset(o_key_pad, 0x5c, SHA256_BLOCK_SIZE);
177 	memset(i_key_pad, 0x36, SHA256_BLOCK_SIZE);
178 	for (i = 0; i < key_len; i++) {
179 		o_key_pad[i] ^= key[i];
180 		i_key_pad[i] ^= key[i];
181 	}
182 
183 	stc_sha256_hash(inner_hash,
184 			i_key_pad, SHA256_BLOCK_SIZE,
185 			msg, msg_len,
186 			NULL);
187 
188 	stc_sha256_hash(out,
189 			o_key_pad, SHA256_BLOCK_SIZE,
190 			inner_hash, SHA256_HASH_SIZE,
191 			NULL);
192 }
193 
sha256_pbkdf2(const uint8_t * pass,int pass_len,const uint8_t * salt,int salt_len,int n_rounds,uint8_t * key_out)194 static void sha256_pbkdf2(const uint8_t *pass, int pass_len,
195 			  const uint8_t *salt, int salt_len,
196 			  int n_rounds, uint8_t *key_out)
197 {
198 	uint8_t *ext_salt;
199 	uint8_t hash[SHA256_HASH_SIZE];
200 	int i, round;
201 
202 	ext_salt = alloca(salt_len + 4);
203 	memcpy(ext_salt, salt, salt_len);
204 
205 	/* always 0x00000001, as the output size is fixed at SHA256_HASH_SIZE */
206 	ext_salt[salt_len + 0] = 0;
207 	ext_salt[salt_len + 1] = 0;
208 	ext_salt[salt_len + 2] = 0;
209 	ext_salt[salt_len + 3] = 1;
210 
211 	sha256_hmac(pass, pass_len, ext_salt, salt_len + 4, key_out);
212 	memcpy(hash, key_out, SHA256_HASH_SIZE);
213 
214 	for (round = 2; round <= n_rounds; round++) {
215 		sha256_hmac(pass, pass_len, hash, SHA256_HASH_SIZE, hash);
216 
217 		for (i = 0; i < SHA256_HASH_SIZE; i++)
218 			key_out[i] ^= hash[i];
219 	}
220 }
221 
222 /********************************************************************
223  * V1/V2 token handling
224  ********************************************************************/
225 
numinput_to_bits(const char * in,uint8_t * out,unsigned int n_bits)226 static void numinput_to_bits(const char *in, uint8_t *out, unsigned int n_bits)
227 {
228 	int bitpos = 13;
229 
230 	memset(out, 0, (n_bits + 7) / 8);
231 	for (; n_bits; n_bits -= TOKEN_BITS_PER_CHAR, in++) {
232 		uint16_t decoded = (*in - '0') & 0x07;
233 		decoded <<= bitpos;
234 		out[0] |= decoded >> 8;
235 		out[1] |= decoded & 0xff;
236 
237 		bitpos -= TOKEN_BITS_PER_CHAR;
238 		if (bitpos < 0) {
239 			bitpos += 8;
240 			out++;
241 		}
242 	}
243 }
244 
bits_to_numoutput(const uint8_t * in,char * out,unsigned int n_bits)245 static void bits_to_numoutput(const uint8_t *in, char *out, unsigned int n_bits)
246 {
247 	int bitpos = 13;
248 
249 	for (; n_bits; n_bits -= TOKEN_BITS_PER_CHAR, out++) {
250 		uint16_t binary = (in[0] << 8) | in[1];
251 		*out = ((binary >> bitpos) & 0x07) + '0';
252 
253 		bitpos -= TOKEN_BITS_PER_CHAR;
254 		if (bitpos < 0) {
255 			bitpos += 8;
256 			in++;
257 		}
258 	}
259 	*out = 0;
260 }
261 
get_bits(const uint8_t * in,unsigned int start,int n_bits)262 static uint32_t get_bits(const uint8_t *in, unsigned int start, int n_bits)
263 {
264 	uint32_t out = 0;
265 
266 	in += start / 8;
267 	start %= 8;
268 
269 	for (; n_bits > 0; n_bits--) {
270 		out <<= 1;
271 		if ((*in << start) & 0x80)
272 			out |= 0x01;
273 		start++;
274 		if (start == 8) {
275 			start = 0;
276 			in++;
277 		}
278 	}
279 	return out;
280 }
281 
set_bits(uint8_t * out,unsigned int start,int n_bits,uint32_t val)282 static void set_bits(uint8_t *out, unsigned int start, int n_bits, uint32_t val)
283 {
284 	out += start / 8;
285 	start %= 8;
286 	val <<= (32 - n_bits);
287 
288 	for (; n_bits > 0; n_bits--) {
289 		if (val & BIT(31))
290 			*out |= BIT(7 - start);
291 		else
292 			*out &= ~BIT(7 - start);
293 		val <<= 1;
294 		start++;
295 		if (start == 8) {
296 			start = 0;
297 			out++;
298 		}
299 	}
300 }
301 
v2_decode_token(const char * in,struct securid_token * t)302 static int v2_decode_token(const char *in, struct securid_token *t)
303 {
304 	uint8_t d[MAX_TOKEN_BITS / 8 + 2];
305 	int len = strlen(in);
306 	uint16_t token_mac, computed_mac;
307 
308 	if (len < MIN_TOKEN_CHARS || len > MAX_TOKEN_CHARS)
309 		return ERR_BAD_LEN;
310 
311 	/* the last 5 digits provide a checksum for the rest of the string */
312 	numinput_to_bits(&in[len - CHECKSUM_CHARS], d, 15);
313 	token_mac = get_bits(d, 0, 15);
314 	computed_mac = securid_shortmac(in, len - CHECKSUM_CHARS);
315 
316 	if (token_mac != computed_mac)
317 		return ERR_CHECKSUM_FAILED;
318 
319 	t->version = in[0] - '0';
320 	memcpy(&t->serial, &in[VER_CHARS], SERIAL_CHARS);
321 	t->serial[SERIAL_CHARS] = 0;
322 
323 	numinput_to_bits(&in[BINENC_OFS], d, BINENC_BITS);
324 	memcpy(t->enc_seed, d, AES_KEY_SIZE);
325 	t->has_enc_seed = 1;
326 
327 	t->flags = get_bits(d, 128, 16);
328 	t->exp_date = get_bits(d, 144, 14);
329 	t->dec_seed_hash = get_bits(d, 159, 15);
330 	t->device_id_hash = get_bits(d, 174, 15);
331 
332 	return ERR_NONE;
333 }
334 
generate_key_hash(uint8_t * key_hash,const char * pass,const char * devid,uint16_t * device_id_hash,struct securid_token * t)335 static int generate_key_hash(uint8_t *key_hash, const char *pass,
336 	const char *devid, uint16_t *device_id_hash, struct securid_token *t)
337 {
338 	uint8_t key[MAX_PASS + DEVID_CHARS + MAGIC_LEN + 1], *devid_buf;
339 	int pos = 0, devid_len = t->is_smartphone ? 40 : 32;
340 	const uint8_t magic[] = { 0xd8, 0xf5, 0x32, 0x53, 0x82, 0x89, 0x00 };
341 
342 	memset(key, 0, sizeof(key));
343 
344 	if (pass) {
345 		pos = strlen(pass);
346 		if (pos > MAX_PASS)
347 			return ERR_BAD_PASSWORD;
348 		memcpy(key, pass, pos);
349 	}
350 
351 	devid_buf = &key[pos];
352 	if (devid) {
353 		int len = 0;
354 
355 		/*
356 		 * For iPhone/Android ctf strings, the device ID takes up
357 		 * 40 bytes and consists of hex digits + zero padding.
358 		 *
359 		 * For other ctf strings (e.g. --blocks), the device ID takes
360 		 * up 32 bytes and consists of decimal digits + zero padding.
361 		 *
362 		 * If this seed isn't locked to a device, we'll just hash
363 		 * 40 (or 32) zero bytes, below.
364 		 */
365 		for (; *devid; devid++) {
366 			if (++len > devid_len)
367 				break;
368 			if ((t->version == 1 && isdigit(*devid)) ||
369 			    (t->version >= 2 && !isxdigit(*devid)))
370 				continue;
371 			key[pos++] = toupper(*devid);
372 		}
373 	}
374 	if (device_id_hash)
375 		*device_id_hash = securid_shortmac(devid_buf, devid_len);
376 
377 	memcpy(&key[pos], magic, MAGIC_LEN);
378 	securid_mac(key, pos + MAGIC_LEN, key_hash);
379 
380 	return ERR_NONE;
381 }
382 
v2_decrypt_seed(struct securid_token * t,const char * pass,const char * devid)383 static int v2_decrypt_seed(struct securid_token *t, const char *pass,
384 			   const char *devid)
385 {
386 	uint8_t key_hash[AES_BLOCK_SIZE], dec_seed_hash[AES_BLOCK_SIZE];
387 	uint16_t computed_mac;
388 	uint16_t device_id_hash;
389 	int rc;
390 
391 	rc = generate_key_hash(key_hash, pass, devid, &device_id_hash, t);
392 	if (rc)
393 		return rc;
394 
395 	if (t->flags & FL_SNPROT && device_id_hash != t->device_id_hash)
396 		return ERR_BAD_DEVID;
397 
398 	stc_aes128_ecb_decrypt(key_hash, t->enc_seed, t->dec_seed);
399 	securid_mac(t->dec_seed, AES_KEY_SIZE, dec_seed_hash);
400 	computed_mac = (dec_seed_hash[0] << 7) | (dec_seed_hash[1] >> 1);
401 
402 	if (computed_mac != t->dec_seed_hash)
403 		return ERR_DECRYPT_FAILED;
404 	t->has_dec_seed = 1;
405 
406 	return ERR_NONE;
407 }
408 
key_from_time(const uint8_t * bcd_time,int bcd_time_bytes,const uint8_t * serial,uint8_t * key)409 static void key_from_time(const uint8_t *bcd_time, int bcd_time_bytes,
410 	const uint8_t *serial, uint8_t *key)
411 {
412 	int i;
413 
414 	memset(key, 0xaa, 8);
415 	memcpy(key, bcd_time, bcd_time_bytes);
416 	memset(key + 12, 0xbb, 4);
417 
418 	/* write BCD-encoded partial serial number */
419 	key += 8;
420 	for (i = 4; i < 12; i += 2)
421 		*(key++) = ((serial[i] - '0') << 4) |
422 			    (serial[i + 1] - '0');
423 }
424 
bcd_write(uint8_t * out,int val,unsigned int bytes)425 static void bcd_write(uint8_t *out, int val, unsigned int bytes)
426 {
427 	out += bytes - 1;
428 	for (; bytes; bytes--) {
429 		*out = val % 10;
430 		val /= 10;
431 		*(out--) |= (val % 10) << 4;
432 		val /= 10;
433 	}
434 }
435 
v2_encode_token(struct securid_token * t,const char * pass,const char * devid,char * out)436 static int v2_encode_token(struct securid_token *t, const char *pass,
437 			   const char *devid, char *out)
438 {
439 	uint8_t d[MAX_TOKEN_BITS / 8 + 2];
440 	uint8_t key_hash[AES_BLOCK_SIZE];
441 	int rc;
442 
443 	rc = generate_key_hash(key_hash, pass, devid, &t->device_id_hash, t);
444 	if (rc)
445 		return rc;
446 
447 	memset(d, 0, sizeof(d));
448 	stc_aes128_ecb_encrypt(key_hash, t->dec_seed, t->enc_seed);
449 	memcpy(d, t->enc_seed, AES_KEY_SIZE);
450 
451 	set_bits(d, 128, 16, t->flags);
452 	set_bits(d, 144, 14, t->exp_date);
453 	set_bits(d, 159, 15, securid_shortmac(t->dec_seed, AES_KEY_SIZE));
454 	set_bits(d, 174, 15, t->device_id_hash);
455 
456 	sprintf(out, "2%s", t->serial);
457 	bits_to_numoutput(d, &out[BINENC_OFS], BINENC_BITS);
458 
459 	set_bits(d, 0, 15, securid_shortmac(out, CHECKSUM_OFS));
460 	bits_to_numoutput(d, &out[CHECKSUM_OFS], CHECKSUM_BITS);
461 
462 	return ERR_NONE;
463 }
464 
465 /********************************************************************
466  * V3 token handling
467  ********************************************************************/
468 
v3_derive_key(const char * pass,const char * devid,const uint8_t * salt,int key_id,uint8_t * out)469 static void v3_derive_key(const char *pass, const char *devid, const uint8_t *salt,
470 			  int key_id, uint8_t *out)
471 {
472 	uint8_t *buf0, *buf1;
473 	int pass_len = pass ? strlen(pass) : 0;
474 	int buf_len = V3_DEVID_CHARS + 16 + V3_NONCE_BYTES + pass_len;
475 	unsigned int i;
476 	const uint8_t key0[] = { 0xd0, 0x14, 0x43, 0x3c, 0x6d, 0x17, 0x9f, 0xeb,
477 				 0xda, 0x09, 0xab, 0xfc, 0x32, 0x49, 0x63, 0x4c };
478 	const uint8_t key1[] = { 0x3b, 0xaf, 0xff, 0x4d, 0x91, 0x8d, 0x89, 0xb6,
479 				 0x81, 0x60, 0xde, 0x44, 0x4e, 0x05, 0xc0, 0xdd };
480 
481 	buf0 = alloca(buf_len);
482 	buf1 = alloca(buf_len >> 1);
483 
484 	memset(buf0, 0, buf_len);
485 
486 	if (pass)
487 		strncpy(buf0, pass, pass_len);
488 	if (devid)
489 		strncpy(&buf0[pass_len], devid, V3_DEVID_CHARS);
490 	memcpy(&buf0[pass_len + V3_DEVID_CHARS], key_id ? key1 : key0, 16);
491 	memcpy(&buf0[pass_len + V3_DEVID_CHARS + 16], salt, V3_NONCE_BYTES);
492 
493 	/* yup, the PBKDF2 password is really "every 2nd byte of the input" */
494 	for (i = 1; i < buf_len; i += 2)
495 		buf1[i >> 1] = buf0[i];
496 
497 	sha256_pbkdf2(buf1, buf_len >> 1, salt, V3_NONCE_BYTES, 1000, out);
498 }
499 
v3_decode_token(const char * in,struct securid_token * t)500 static int v3_decode_token(const char *in, struct securid_token *t)
501 {
502 	char decoded[V3_BASE64_SIZE];
503 	int i, j;
504 	unsigned long actual;
505 
506 	/* remove URL-encoding */
507 	for (i = 0, j = 0; in[i]; ) {
508 		if (j == V3_BASE64_SIZE - 1)
509 			return ERR_BAD_LEN;
510 		if (in[i] == '%') {
511 			if (!isxdigit(in[i + 1]) || !isxdigit(in[i + 2]))
512 				return ERR_BAD_LEN;
513 			decoded[j++] = hex2byte(&in[i + 1]);
514 			i += 3;
515 		} else {
516 			decoded[j++] = in[i++];
517 		}
518 	}
519 	decoded[j] = 0;
520 
521 	actual = sizeof(struct v3_token);
522 	t->v3 = malloc(actual);
523 	if (!t->v3)
524 		return ERR_NO_MEMORY;
525 
526 	if (stc_b64_decode(decoded, strlen(decoded), (void *)t->v3, &actual) ||
527 	    actual != sizeof(struct v3_token) ||
528 	    t->v3->version != 0x03) {
529 		free(t->v3);
530 		t->v3 = NULL;
531 		return ERR_GENERAL;
532 	}
533 
534 	t->version = 3;
535 
536 	/* more flags will get populated later when we decrypt the payload */
537 	t->flags = t->v3->password_locked ? FL_PASSPROT : 0;
538 	t->flags |= t->v3->devid_locked ? FL_SNPROT : 0;
539 
540 	return ERR_NONE;
541 }
542 
v3_parse_date(uint8_t * in)543 static uint16_t v3_parse_date(uint8_t *in)
544 {
545 	uint64_t longdate;
546 
547 	longdate = ((uint64_t)in[0] << 32) |
548 		   ((uint64_t)in[1] << 24) |
549 		   ((uint64_t)in[2] << 16) |
550 		   ((uint64_t)in[3] <<  8) |
551 		   ((uint64_t)in[4] <<  0);
552 	longdate /= SECURID_V3_DAY;
553 	longdate -= SECURID_EPOCH_DAYS;
554 	return longdate <= SECURID_MAX_DATE ? longdate : SECURID_MAX_DATE;
555 }
556 
v3_encode_date(uint8_t * out,uint16_t in)557 static void v3_encode_date(uint8_t *out, uint16_t in)
558 {
559 	uint64_t longdate;
560 
561 	longdate = ((uint64_t)in + SECURID_EPOCH_DAYS) * SECURID_V3_DAY;
562 	out[0] = longdate >> 32;
563 	out[1] = longdate >> 24;
564 	out[2] = longdate >> 16;
565 	out[3] = longdate >>  8;
566 	out[4] = longdate >>  0;
567 }
568 
v3_compute_hash(const char * pass,const char * devid,const uint8_t * salt,uint8_t * hash)569 static void v3_compute_hash(const char *pass, const char *devid,
570 			    const uint8_t *salt, uint8_t *hash)
571 {
572 	uint8_t hash_buf[V3_NONCE_BYTES + V3_DEVID_CHARS + MAX_PASS];
573 	int pass_len = 0;
574 
575 	memset(hash_buf, 0, sizeof(hash_buf));
576 	memcpy(&hash_buf[0], salt, V3_NONCE_BYTES);
577 
578 	if (devid)
579 		strncpy(&hash_buf[V3_NONCE_BYTES], devid, V3_DEVID_CHARS);
580 
581 	if (pass) {
582 		pass_len = strlen(pass);
583 		strncpy(&hash_buf[V3_NONCE_BYTES + V3_DEVID_CHARS], pass, MAX_PASS);
584 	}
585 	stc_sha256_hash(hash,
586 			hash_buf, V3_NONCE_BYTES + V3_DEVID_CHARS + pass_len,
587 			NULL);
588 }
589 
v3_compute_hmac(struct v3_token * v3,const char * pass,const char * devid,uint8_t * out)590 static void v3_compute_hmac(struct v3_token *v3, const char *pass,
591 			    const char *devid, uint8_t *out)
592 {
593 	uint8_t hash[SHA256_HASH_SIZE];
594 
595 	v3_derive_key(pass, devid, v3->nonce, 0, hash);
596 	sha256_hmac(hash, SHA256_HASH_SIZE,
597 		    (void *)v3, sizeof(*v3) - SHA256_HASH_SIZE, out);
598 }
599 
v3_scrub_devid(const char * in,char * out)600 static void v3_scrub_devid(const char *in, char *out)
601 {
602 	int j;
603 	for (j = 0; in && *in && j < V3_DEVID_CHARS; in++) {
604 		if (isalnum(*in))
605 			out[j++] = toupper(*in);
606 	}
607 	out[j] = 0;
608 }
609 
v3_decrypt_seed(struct securid_token * t,const char * pass,const char * raw_devid)610 static int v3_decrypt_seed(struct securid_token *t,
611 			   const char *pass, const char *raw_devid)
612 {
613 	struct v3_payload payload;
614 	uint8_t hash[SHA256_HASH_SIZE];
615 	char devid[V3_DEVID_CHARS + 1];
616 
617 	v3_scrub_devid(raw_devid, devid);
618 
619 	v3_compute_hash(NULL, devid, t->v3->nonce, hash);
620 	if (memcmp(hash, t->v3->nonce_devid_hash, SHA256_HASH_SIZE) != 0)
621 		return ERR_BAD_DEVID;
622 
623 	v3_compute_hash(pass, devid, t->v3->nonce, hash);
624 	if (memcmp(hash, t->v3->nonce_devid_pass_hash, SHA256_HASH_SIZE) != 0)
625 		return ERR_DECRYPT_FAILED;
626 
627 	v3_compute_hmac(t->v3, pass, devid, hash);
628 	if (memcmp(hash, t->v3->mac, SHA256_HASH_SIZE) != 0)
629 		return ERR_CHECKSUM_FAILED;
630 
631 	v3_derive_key(pass, devid, t->v3->nonce, 1, hash);
632 	stc_aes256_cbc_decrypt(hash,
633 			   t->v3->enc_payload, sizeof(struct v3_payload),
634 			   t->v3->nonce, (void *)&payload);
635 
636 	if (strlen(payload.serial) != SERIAL_CHARS)
637 		return ERR_GENERAL;
638 	strncpy(t->serial, payload.serial, SERIAL_CHARS);
639 	t->serial[SERIAL_CHARS] = 0;
640 
641 	memcpy(t->dec_seed, &payload.dec_seed, AES_KEY_SIZE);
642 	t->has_dec_seed = 1;
643 
644 	t->flags |= FL_TIMESEEDS | FL_128BIT;
645 	t->flags |= payload.mode ? FL_FEAT4 : 0;
646 	t->flags |= ((payload.digits-1) << FLD_DIGIT_SHIFT) & FLD_DIGIT_MASK;
647 	t->flags |= (payload.addpin != V3_ADDPIN_OFF) ?
648 		    (0x2 << FLD_PINMODE_SHIFT) : 0;
649 	t->flags |= payload.interval == 60 ? (1 << FLD_NUMSECONDS_SHIFT) : 0;
650 
651 	t->exp_date = v3_parse_date(payload.exp_date);
652 
653 	return ERR_NONE;
654 }
655 
v3_encode_token(struct securid_token * t,const char * pass,const char * raw_devid,char * out)656 static int v3_encode_token(struct securid_token *t, const char *pass,
657 			   const char *raw_devid, char *out)
658 {
659 	struct v3_payload payload;
660 	struct v3_token v3;
661 	uint8_t key[SHA256_HASH_SIZE];
662 	unsigned long enclen = V3_BASE64_SIZE;
663 	char raw_b64[V3_BASE64_SIZE];
664 	char devid[V3_DEVID_CHARS + 1];
665 	int i;
666 
667 	memset(&payload, 0, sizeof(payload));
668 	strncpy(payload.serial, t->serial, sizeof(payload.serial));
669 	memcpy(payload.dec_seed, t->dec_seed, AES_KEY_SIZE);
670 	payload.unk0[0] = payload.unk0[1] = 1;
671 	payload.mode = !!(t->flags & FL_FEAT4);
672 	payload.digits = ((t->flags & FLD_DIGIT_MASK) >> FLD_DIGIT_SHIFT) + 1;
673 	payload.addpin = (t->flags & (0x2 << FLD_PINMODE_SHIFT)) ?
674 			 V3_ADDPIN_ON : V3_ADDPIN_OFF;
675 	payload.interval = (t->flags & FLD_NUMSECONDS_MASK) ? 60 : 30;
676 
677 	v3_encode_date(payload.exp_date, t->exp_date);
678 
679 	memset(payload.padding, 0x10, 0x10);
680 
681 	memset(&v3, 0, sizeof(v3));
682 	if (securid_rand(v3.nonce, sizeof(v3.nonce), 0))
683 		return ERR_GENERAL;
684 
685 	v3.version = 3;
686 	v3.password_locked = !!pass;
687 	v3.devid_locked = !!raw_devid;
688 
689 	v3_scrub_devid(raw_devid, devid);
690 	v3_derive_key(pass, devid, v3.nonce, 1, key);
691 	stc_aes256_cbc_encrypt(key,
692 			   (void *)&payload, sizeof(struct v3_payload),
693 			   v3.nonce, v3.enc_payload);
694 
695 	v3_compute_hash(NULL, devid, v3.nonce, v3.nonce_devid_hash);
696 	v3_compute_hash(pass, devid, v3.nonce, v3.nonce_devid_pass_hash);
697 	v3_compute_hmac(&v3, pass, devid, v3.mac);
698 
699 	stc_b64_encode((void *)&v3, sizeof(v3), raw_b64, &enclen);
700 
701 	for (i = 0; i < enclen; i++) {
702 		char c = raw_b64[i];
703 		if (!isalnum(c)) {
704 			sprintf(out, "%%%02X", c);
705 			out += 3;
706 		} else
707 			*(out++) = c;
708 	}
709 	*out = 0;
710 
711 	return ERR_NONE;
712 }
713 
714 
715 /********************************************************************
716  * Public functions
717  ********************************************************************/
718 
securid_decode_token(const char * in,struct securid_token * t)719 int securid_decode_token(const char *in, struct securid_token *t)
720 {
721 	/*
722 	 * V1/V2 tokens start with the ASCII version digit
723 	 * V3 tokens always start with a base64-encoded 0x03 byte, which
724 	 *   is guaranteed to encode to 'A'
725 	 */
726 	if (in[0] == '1' || in[0] == '2')
727 		return v2_decode_token(in, t);
728 	else if (strlen(in) >= V3_BASE64_MIN_CHARS && (in[0] == 'A'))
729 		return v3_decode_token(in, t);
730 	else
731 		return ERR_TOKEN_VERSION;
732 }
733 
securid_decrypt_seed(struct securid_token * t,const char * pass,const char * devid)734 int securid_decrypt_seed(struct securid_token *t, const char *pass,
735 			 const char *devid)
736 {
737 	if (t->flags & FL_PASSPROT) {
738 		if (!pass || !strlen(pass))
739 			return ERR_MISSING_PASSWORD;
740 		if (strlen(pass) > MAX_PASS)
741 			return ERR_BAD_PASSWORD;
742 	} else
743 		pass = NULL;
744 
745 	if (t->flags & FL_SNPROT) {
746 		if (!devid || !strlen(devid))
747 			return ERR_MISSING_PASSWORD;
748 		/* NOTE: max length is checked elsewhere, as it varies */
749 	} else
750 		devid = NULL;
751 
752 	if (t->sdtid)
753 		return sdtid_decrypt(t, pass);
754 	else if (t->v3)
755 		return v3_decrypt_seed(t, pass, devid);
756 	else
757 		return v2_decrypt_seed(t, pass, devid);
758 }
759 
securid_check_devid(struct securid_token * t,const char * devid)760 int securid_check_devid(struct securid_token *t, const char *devid)
761 {
762 	int ret = securid_decrypt_seed(t, ".", devid);
763 	if (ret == ERR_BAD_DEVID || ret == ERR_MISSING_PASSWORD)
764 		return ERR_BAD_DEVID;
765 	else
766 		return ERR_NONE;
767 }
768 
securid_compute_tokencode(struct securid_token * t,time_t now,char * code_out)769 void securid_compute_tokencode(struct securid_token *t, time_t now,
770 			       char *code_out)
771 {
772 	uint8_t bcd_time[8];
773 	uint8_t key0[AES_KEY_SIZE], key1[AES_KEY_SIZE];
774 	int i, j;
775 	uint32_t tokencode;
776 	struct tm gmt;
777 	int pin_len = strlen(t->pin);
778 	int is_30 = securid_token_interval(t) == 30;
779 
780 	gmtime_r(&now, &gmt);
781 	bcd_write(&bcd_time[0], gmt.tm_year + 1900, 2);
782 	bcd_write(&bcd_time[2], gmt.tm_mon + 1, 1);
783 	bcd_write(&bcd_time[3], gmt.tm_mday, 1);
784 	bcd_write(&bcd_time[4], gmt.tm_hour, 1);
785 	bcd_write(&bcd_time[5], gmt.tm_min & ~(is_30 ? 0x01 : 0x03), 1);
786 	bcd_time[6] = bcd_time[7] = 0;
787 
788 	key_from_time(bcd_time, 2, t->serial, key0);
789 	stc_aes128_ecb_encrypt(t->dec_seed, key0, key0);
790 	key_from_time(bcd_time, 3, t->serial, key1);
791 	stc_aes128_ecb_encrypt(key0, key1, key1);
792 	key_from_time(bcd_time, 4, t->serial, key0);
793 	stc_aes128_ecb_encrypt(key1, key0, key0);
794 	key_from_time(bcd_time, 5, t->serial, key1);
795 	stc_aes128_ecb_encrypt(key0, key1, key1);
796 	key_from_time(bcd_time, 8, t->serial, key0);
797 	stc_aes128_ecb_encrypt(key1, key0, key0);
798 
799 	/* key0 now contains 4 consecutive token codes */
800 	if (is_30)
801 		i = ((gmt.tm_min & 0x01) << 3) | ((gmt.tm_sec >= 30) << 2);
802 	else
803 		i = (gmt.tm_min & 0x03) << 2;
804 
805 	tokencode = (key0[i + 0] << 24) | (key0[i + 1] << 16) |
806 		    (key0[i + 2] << 8)  | (key0[i + 3] << 0);
807 
808 	/* populate code_out backwards, adding PIN digits if available */
809 	j = ((t->flags & FLD_DIGIT_MASK) >> FLD_DIGIT_SHIFT) + 1;
810 	code_out[j--] = 0;
811 	for (i = 0; j >= 0; j--, i++) {
812 		uint8_t c = tokencode % 10;
813 		tokencode /= 10;
814 
815 		if (i < pin_len)
816 			c += t->pin[pin_len - i - 1] - '0';
817 		code_out[j] = c % 10 + '0';
818 	}
819 }
820 
securid_encode_token(const struct securid_token * t,const char * pass,const char * devid,int version,char * out)821 int securid_encode_token(const struct securid_token *t, const char *pass,
822 			 const char *devid, int version, char *out)
823 {
824 	struct securid_token newt = *t;
825 
826 	/* empty password means "no password" */
827 	if (!pass || !strlen(pass)) {
828 		pass = NULL;
829 		newt.flags &= ~FL_PASSPROT;
830 	} else
831 		newt.flags |= FL_PASSPROT;
832 
833 	if (!devid || !strlen(devid)) {
834 		devid = NULL;
835 		newt.flags &= ~FL_SNPROT;
836 	} else
837 		newt.flags |= FL_SNPROT;
838 
839 	if (version == 3)
840 		return v3_encode_token(&newt, pass, devid, out);
841 	else
842 		return v2_encode_token(&newt, pass, devid, out);
843 }
844 
securid_random_token(struct securid_token * t)845 int securid_random_token(struct securid_token *t)
846 {
847 	time_t now = time(NULL);
848 	uint8_t randbytes[16], key_hash[AES_BLOCK_SIZE];
849 	int i;
850 
851 	memset(t, 0, sizeof(*t));
852 
853 	if (securid_rand(t->dec_seed, AES_KEY_SIZE, 0) ||
854 	    securid_rand(randbytes, sizeof(randbytes), 0))
855 		return ERR_GENERAL;
856 
857 	t->dec_seed_hash = securid_shortmac(t->dec_seed, AES_KEY_SIZE);
858 
859 	generate_key_hash(key_hash, NULL, NULL, &t->device_id_hash, t);
860 	stc_aes128_ecb_encrypt(key_hash, t->dec_seed, t->enc_seed);
861 	t->has_enc_seed = 1;
862 
863 	t->version = 2;
864 	t->flags = FL_TIMESEEDS | FLD_DIGIT_MASK | FLD_PINMODE_MASK |
865 		   (1 << FLD_NUMSECONDS_SHIFT) | FL_128BIT;
866 	t->pinmode = 3;
867 
868 	for (i = 0; i < 12; i++)
869 		t->serial[i] = '0' + randbytes[i] % 10;
870 
871 	/* set the expiration date a couple of months out */
872 	t->exp_date = (now - SECURID_EPOCH) / (24 * 60 * 60) + 60 +
873 		(randbytes[12] & 0x0f) * 30;
874 
875 	return ERR_NONE;
876 }
877 
securid_unix_exp_date(const struct securid_token * t)878 time_t securid_unix_exp_date(const struct securid_token *t)
879 {
880 	/*
881 	 * v3 tokens encrypt the expiration date, so if the user has not
882 	 * been prompted for a password yet, we'll need to bypass the
883 	 * expiration checks.
884 	 */
885 	if (t->version == 3 && !t->exp_date)
886 		return MAX_TIME_T;
887 	if (t->exp_date > SECURID_MAX_DATE)
888 		return MAX_TIME_T;
889 
890 	return SECURID_EPOCH + (t->exp_date + 1) * 60 * 60 * 24;
891 }
892 
securid_token_interval(const struct securid_token * t)893 int securid_token_interval(const struct securid_token *t)
894 {
895 	if (((t->flags & FLD_NUMSECONDS_MASK) >> FLD_NUMSECONDS_SHIFT) == 0)
896 		return 30;
897 	else
898 		return 60;
899 }
900 
securid_token_info(const struct securid_token * t,void (* callback)(const char * key,const char * value))901 void securid_token_info(const struct securid_token *t,
902 	void (*callback)(const char *key, const char *value))
903 {
904 	char str[256];
905 	unsigned int i;
906 	struct tm exp_tm;
907 	time_t exp_unix_time = securid_unix_exp_date(t);
908 
909 	callback("Serial number", t->serial);
910 
911 	if (t->has_dec_seed) {
912 		for (i = 0; i < AES_KEY_SIZE; i++)
913 			sprintf(&str[i * 3], "%02x ", t->dec_seed[i]);
914 		callback("Decrypted seed", str);
915 	}
916 
917 	if (t->has_enc_seed) {
918 		for (i = 0; i < AES_KEY_SIZE; i++)
919 			sprintf(&str[i * 3], "%02x ", t->enc_seed[i]);
920 		callback("Encrypted seed", str);
921 
922 		callback("Encrypted w/password",
923 			t->flags & FL_PASSPROT ? "yes" : "no");
924 		callback("Encrypted w/devid",
925 			t->flags & FL_SNPROT ? "yes" : "no");
926 	}
927 
928 	gmtime_r(&exp_unix_time, &exp_tm);
929 	strftime(str, 32, "%Y/%m/%d", &exp_tm);
930 	callback("Expiration date", str);
931 
932 	callback("Key length", t->flags & FL_128BIT ? "128" : "64");
933 
934 	sprintf(str, "%d",
935 		((t->flags & FLD_DIGIT_MASK) >> FLD_DIGIT_SHIFT) + 1);
936 	callback("Tokencode digits", str);
937 
938 	sprintf(str, "%d",
939 		((t->flags & FLD_PINMODE_MASK) >> FLD_PINMODE_SHIFT));
940 	callback("PIN mode", str);
941 
942 	switch ((t->flags & FLD_NUMSECONDS_MASK) >> FLD_NUMSECONDS_SHIFT) {
943 	case 0x00:
944 		strcpy(str, "30");
945 		break;
946 	case 0x01:
947 		strcpy(str, "60");
948 		break;
949 	default:
950 		strcpy(str, "unknown");
951 	}
952 	callback("Seconds per tokencode", str);
953 
954 	callback("App-derived", t->flags & FL_APPSEEDS ? "yes" : "no");
955 	callback("Feature bit 4", t->flags & FL_FEAT4 ? "yes" : "no");
956 	callback("Time-derived", t->flags & FL_TIMESEEDS ? "yes" : "no");
957 	callback("Feature bit 6", t->flags & FL_FEAT6 ? "yes" : "no");
958 }
959 
securid_check_exp(struct securid_token * t,time_t now)960 int securid_check_exp(struct securid_token *t, time_t now)
961 {
962 	time_t exp_unix_time = securid_unix_exp_date(t);
963 	const int halfday = 60 * 60 * 12, wholeday = 60 * 60 * 24;
964 
965 	/*
966 	 * Other soft token implementations seem to allow ~12hrs as a grace
967 	 * period.  Actual results will depend on how soon the server cuts
968 	 * off expired tokens.
969 	 */
970 	exp_unix_time += halfday;
971 	exp_unix_time -= now;
972 	return exp_unix_time / wholeday;
973 }
974 
securid_pin_format_ok(const char * pin)975 int securid_pin_format_ok(const char *pin)
976 {
977 	int i, rc;
978 
979 	rc = strlen(pin);
980 	if (rc < MIN_PIN || rc > MAX_PIN)
981 		return ERR_BAD_LEN;
982 	for (i = 0; i < rc; i++)
983 		if (!isdigit(pin[i]))
984 			return ERR_GENERAL;
985 	return ERR_NONE;
986 }
987 
securid_pin_required(const struct securid_token * t)988 int securid_pin_required(const struct securid_token *t)
989 {
990 	return ((t->flags & FLD_PINMODE_MASK) >> FLD_PINMODE_SHIFT) >= 2;
991 }
992 
securid_pass_required(const struct securid_token * t)993 int securid_pass_required(const struct securid_token *t)
994 {
995 	return !!(t->flags & FL_PASSPROT);
996 }
997 
securid_devid_required(const struct securid_token * t)998 int securid_devid_required(const struct securid_token *t)
999 {
1000 	return !!(t->flags & FL_SNPROT);
1001 }
1002 
securid_encrypt_pin(const char * pin,const char * password)1003 char *securid_encrypt_pin(const char *pin, const char *password)
1004 {
1005 	int i;
1006 	uint8_t buf[AES_BLOCK_SIZE], iv[AES_BLOCK_SIZE],
1007 		passhash[AES_BLOCK_SIZE], *ret;
1008 
1009 	if (securid_pin_format_ok(pin) != ERR_NONE)
1010 		return NULL;
1011 
1012 	memset(buf, 0, sizeof(buf));
1013 	strcpy(buf, pin);
1014 	buf[AES_BLOCK_SIZE - 1] = strlen(pin);
1015 
1016 	securid_mac(password, strlen(password), passhash);
1017 
1018 	if (securid_rand(iv, AES_BLOCK_SIZE, 0))
1019 		return NULL;
1020 
1021 	for (i = 0; i < AES_BLOCK_SIZE; i++)
1022 		buf[i] ^= iv[i];
1023 	stc_aes128_ecb_encrypt(passhash, buf, buf);
1024 
1025 	ret = malloc(AES_BLOCK_SIZE * 2 * 2 + 1);
1026 	if (!ret)
1027 		return NULL;
1028 
1029 	for (i = 0; i < AES_BLOCK_SIZE; i++)
1030 		sprintf(&ret[i * 2], "%02x", iv[i]);
1031 	for (i = 0; i < AES_BLOCK_SIZE; i++)
1032 		sprintf(&ret[(AES_BLOCK_SIZE + i) * 2], "%02x", buf[i]);
1033 
1034 	return ret;
1035 }
1036 
securid_decrypt_pin(const char * enc_pin,const char * password,char * pin)1037 int securid_decrypt_pin(const char *enc_pin, const char *password, char *pin)
1038 {
1039 	int i;
1040 	uint8_t buf[AES_BLOCK_SIZE], iv[AES_BLOCK_SIZE],
1041 		passhash[AES_BLOCK_SIZE];
1042 
1043 	if (strlen(enc_pin) != AES_BLOCK_SIZE * 2 * 2)
1044 		return ERR_BAD_LEN;
1045 
1046 	for (i = 0; i < AES_BLOCK_SIZE; i++) {
1047 		iv[i] = hex2byte(&enc_pin[i * 2]);
1048 		buf[i] = hex2byte(&enc_pin[(i + AES_BLOCK_SIZE) * 2]);
1049 	}
1050 
1051 	securid_mac(password, strlen(password), passhash);
1052 	stc_aes128_ecb_decrypt(passhash, buf, buf);
1053 
1054 	for (i = 0; i < AES_BLOCK_SIZE; i++)
1055 		buf[i] ^= iv[i];
1056 
1057 	if (buf[AES_BLOCK_SIZE - 2] != 0 ||
1058 	    buf[AES_BLOCK_SIZE - 1] != strlen(buf))
1059 		return ERR_GENERAL;
1060 	if (securid_pin_format_ok(buf) != ERR_NONE)
1061 		return ERR_GENERAL;
1062 
1063 	strcpy(pin, buf);
1064 	return ERR_NONE;
1065 }
1066