|
@@ -69,9 +69,9 @@ static void LOG_func(const char *msg) {
|
69
|
69
|
LOG(msg);
|
70
|
70
|
}
|
71
|
71
|
|
72
|
|
-static const char short_options[] = "i:d:N:Sl:L:F:I:RzM:T:W:O:o:t:rk:g:pwxyc:C:Y:A:s:U:P:B:eZ:Ef:X:H:G:KJ:D:jbhV";
|
|
72
|
+static const char short_options[] = "i:d:N:Sl:L:F:I:RzM:T:W:O:o:t:rk:g:pwxyc:C:Y:Q:A:s:U:P:B:eZ:Ef:X:H:G:KJ:D:jbhV";
|
73
|
73
|
|
74
|
|
-// Unused short options: Qamnquv0123456789
|
|
74
|
+// Unused short options: amnquv0123456789
|
75
|
75
|
static const struct option long_options[] = {
|
76
|
76
|
{ "ident", required_argument, NULL, 'i' },
|
77
|
77
|
{ "daemon", required_argument, NULL, 'd' },
|
|
@@ -103,6 +103,7 @@ static const struct option long_options[] = {
|
103
|
103
|
{ "ca-system", required_argument, NULL, 'c' },
|
104
|
104
|
{ "caid", required_argument, NULL, 'C' },
|
105
|
105
|
{ "const-cw", required_argument, NULL, 'Y' },
|
|
106
|
+ { "biss-key", required_argument, NULL, 'Q' },
|
106
|
107
|
|
107
|
108
|
{ "camd-proto", required_argument, NULL, 'A' },
|
108
|
109
|
{ "camd-server", required_argument, NULL, 's' },
|
|
@@ -175,6 +176,8 @@ static void show_help(struct ts *ts) {
|
175
|
176
|
printf(" -C --caid <caid> | Set CAID. Default: Taken from --ca-system.\n");
|
176
|
177
|
printf(" -Y --const-cw <codeword> | Set constant code word for decryption.\n");
|
177
|
178
|
printf(" . Example cw: a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8\n");
|
|
179
|
+ printf(" -Q --biss-key <biss-key> | Set BISS key for decryption.\n");
|
|
180
|
+ printf(" . Example key: 112233445566\n");
|
178
|
181
|
printf("\n");
|
179
|
182
|
printf("CAMD server options:\n");
|
180
|
183
|
printf(" -A --camd-proto <proto> | Set CAMD network protocol.\n");
|
|
@@ -369,6 +372,28 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
369
|
372
|
camd_set_cw(ts, ts->camd.key->cw, 0);
|
370
|
373
|
ts->camd.key->is_valid_cw = 1;
|
371
|
374
|
break;
|
|
375
|
+ case 'Q': // --biss-key
|
|
376
|
+ ts->camd.constant_codeword = 1;
|
|
377
|
+ if (strlen(optarg) > 2 && optarg[0] == '0' && optarg[1] == 'x')
|
|
378
|
+ optarg += 2;
|
|
379
|
+ if (strlen(optarg) != BISSKEY_LENGTH * 2) {
|
|
380
|
+ fprintf(stderr, "ERROR: BISS key should be %u characters long.\n", BISSKEY_LENGTH * 2);
|
|
381
|
+ exit(EXIT_FAILURE);
|
|
382
|
+ }
|
|
383
|
+ uint8_t *key = ts->camd.key->cw;
|
|
384
|
+ if (decode_hex_string(optarg, key, strlen(optarg)) < 0) {
|
|
385
|
+ fprintf(stderr, "ERROR: Invalid hex string for BISS key: %s\n", optarg);
|
|
386
|
+ exit(EXIT_FAILURE);
|
|
387
|
+ }
|
|
388
|
+ // Calculate BISS KEY crc
|
|
389
|
+ memmove(key + 4, key + 3, 3);
|
|
390
|
+ key[3] = (uint8_t)(key[0] + key[1] + key[2]);
|
|
391
|
+ key[7] = (uint8_t)(key[4] + key[5] + key[6]);
|
|
392
|
+ // Even and odd keys are the same
|
|
393
|
+ memcpy(key + 8, key, 8);
|
|
394
|
+ camd_set_cw(ts, ts->camd.key->cw, 0);
|
|
395
|
+ ts->camd.key->is_valid_cw = 1;
|
|
396
|
+ break;
|
372
|
397
|
|
373
|
398
|
case 'A': // --camd-proto
|
374
|
399
|
if (strcasecmp(optarg, "cs378x") == 0) {
|