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