diff options
Diffstat (limited to 'utils/sbtools/misc.c')
-rw-r--r-- | utils/sbtools/misc.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/utils/sbtools/misc.c b/utils/sbtools/misc.c new file mode 100644 index 0000000000..09a8919aef --- /dev/null +++ b/utils/sbtools/misc.c | |||
@@ -0,0 +1,174 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include <stdlib.h> | ||
22 | #include <stdio.h> | ||
23 | #include <time.h> | ||
24 | #include <ctype.h> | ||
25 | #include "misc.h" | ||
26 | |||
27 | bool g_debug = false; | ||
28 | |||
29 | /** | ||
30 | * Misc | ||
31 | */ | ||
32 | |||
33 | char *s_getenv(const char *name) | ||
34 | { | ||
35 | char *s = getenv(name); | ||
36 | return s ? s : ""; | ||
37 | } | ||
38 | |||
39 | void generate_random_data(void *buf, size_t sz) | ||
40 | { | ||
41 | FILE *rand_fd = fopen("/dev/urandom", "rb"); | ||
42 | if(rand_fd == NULL) | ||
43 | bugp("failed to open /dev/urandom"); | ||
44 | if(fread(buf, 1, sz, rand_fd) != sz) | ||
45 | bugp("failed to read /dev/urandom"); | ||
46 | fclose(rand_fd); | ||
47 | } | ||
48 | |||
49 | void *xmalloc(size_t s) | ||
50 | { | ||
51 | void * r = malloc(s); | ||
52 | if(!r) bugp("malloc"); | ||
53 | return r; | ||
54 | } | ||
55 | |||
56 | int convxdigit(char digit, byte *val) | ||
57 | { | ||
58 | if(digit >= '0' && digit <= '9') | ||
59 | { | ||
60 | *val = digit - '0'; | ||
61 | return 0; | ||
62 | } | ||
63 | else if(digit >= 'A' && digit <= 'F') | ||
64 | { | ||
65 | *val = digit - 'A' + 10; | ||
66 | return 0; | ||
67 | } | ||
68 | else if(digit >= 'a' && digit <= 'f') | ||
69 | { | ||
70 | *val = digit - 'a' + 10; | ||
71 | return 0; | ||
72 | } | ||
73 | else | ||
74 | return 1; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * Key file parsing | ||
79 | */ | ||
80 | int g_nr_keys; | ||
81 | key_array_t g_key_array; | ||
82 | |||
83 | void add_keys(key_array_t ka, int kac) | ||
84 | { | ||
85 | key_array_t new_ka = xmalloc((g_nr_keys + kac) * sizeof(struct crypto_key_t)); | ||
86 | memcpy(new_ka, g_key_array, g_nr_keys * sizeof(struct crypto_key_t)); | ||
87 | memcpy(new_ka + g_nr_keys, ka, kac * sizeof(struct crypto_key_t)); | ||
88 | free(g_key_array); | ||
89 | g_key_array = new_ka; | ||
90 | g_nr_keys += kac; | ||
91 | } | ||
92 | |||
93 | key_array_t read_keys(const char *key_file, int *num_keys) | ||
94 | { | ||
95 | int size; | ||
96 | FILE *fd = fopen(key_file, "r"); | ||
97 | if(fd == NULL) | ||
98 | bugp("opening key file failed"); | ||
99 | fseek(fd, 0, SEEK_END); | ||
100 | size = ftell(fd); | ||
101 | fseek(fd, 0, SEEK_SET); | ||
102 | char *buf = xmalloc(size); | ||
103 | if(fread(buf, size, 1, fd) != (size_t)size) | ||
104 | bugp("reading key file"); | ||
105 | fclose(fd); | ||
106 | |||
107 | if(g_debug) | ||
108 | printf("Parsing key file '%s'...\n", key_file); | ||
109 | *num_keys = size ? 1 : 0; | ||
110 | char *ptr = buf; | ||
111 | /* allow trailing newline at the end (but no space after it) */ | ||
112 | while(ptr != buf + size && (ptr + 1) != buf + size) | ||
113 | { | ||
114 | if(*ptr++ == '\n') | ||
115 | (*num_keys)++; | ||
116 | } | ||
117 | |||
118 | key_array_t keys = xmalloc(sizeof(struct crypto_key_t) * *num_keys); | ||
119 | int pos = 0; | ||
120 | for(int i = 0; i < *num_keys; i++) | ||
121 | { | ||
122 | /* skip ws */ | ||
123 | while(pos < size && isspace(buf[pos])) | ||
124 | pos++; | ||
125 | /* enough space ? */ | ||
126 | if((pos + 32) > size) | ||
127 | bugp("invalid key file"); | ||
128 | keys[i].method = CRYPTO_KEY; | ||
129 | for(int j = 0; j < 16; j++) | ||
130 | { | ||
131 | byte a, b; | ||
132 | if(convxdigit(buf[pos + 2 * j], &a) || convxdigit(buf[pos + 2 * j + 1], &b)) | ||
133 | bugp(" invalid key, it should be a 128-bit key written in hexadecimal\n"); | ||
134 | keys[i].u.key[j] = (a << 4) | b; | ||
135 | } | ||
136 | if(g_debug) | ||
137 | { | ||
138 | printf("Add key: "); | ||
139 | for(int j = 0; j < 16; j++) | ||
140 | printf("%02x", keys[i].u.key[j]); | ||
141 | printf("\n"); | ||
142 | } | ||
143 | pos += 32; | ||
144 | } | ||
145 | free(buf); | ||
146 | |||
147 | return keys; | ||
148 | } | ||
149 | |||
150 | void print_hex(byte *data, int len, bool newline) | ||
151 | { | ||
152 | for(int i = 0; i < len; i++) | ||
153 | printf("%02X ", data[i]); | ||
154 | if(newline) | ||
155 | printf("\n"); | ||
156 | } | ||
157 | |||
158 | void print_key(struct crypto_key_t *key, bool newline) | ||
159 | { | ||
160 | switch(key->method) | ||
161 | { | ||
162 | case CRYPTO_KEY: | ||
163 | print_hex(key->u.key, 16, false); | ||
164 | break; | ||
165 | case CRYPTO_USBOTP: | ||
166 | printf("USB-OTP(%04x:%04x)", key->u.vid_pid >> 16, key->u.vid_pid & 0xffff); | ||
167 | break; | ||
168 | case CRYPTO_NONE: | ||
169 | printf("none"); | ||
170 | break; | ||
171 | } | ||
172 | if(newline) | ||
173 | printf("\n"); | ||
174 | } | ||