summaryrefslogtreecommitdiff
path: root/utils/sbtools/elftosb.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/sbtools/elftosb.c')
-rw-r--r--utils/sbtools/elftosb.c270
1 files changed, 92 insertions, 178 deletions
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c
index 17b72417cf..5e65ba3261 100644
--- a/utils/sbtools/elftosb.c
+++ b/utils/sbtools/elftosb.c
@@ -21,13 +21,8 @@
21 21
22#define _ISOC99_SOURCE 22#define _ISOC99_SOURCE
23#include <stdio.h> 23#include <stdio.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27#include <errno.h> 24#include <errno.h>
28#include <unistd.h>
29#include <stdlib.h> 25#include <stdlib.h>
30#include <inttypes.h>
31#include <string.h> 26#include <string.h>
32#include <ctype.h> 27#include <ctype.h>
33#include <time.h> 28#include <time.h>
@@ -39,143 +34,18 @@
39#include "elf.h" 34#include "elf.h"
40#include "sb.h" 35#include "sb.h"
41#include "dbparser.h" 36#include "dbparser.h"
37#include "misc.h"
42 38
43#define _STR(a) #a
44#define STR(a) _STR(a)
45
46#define bug(...) do { fprintf(stderr,"["__FILE__":"STR(__LINE__)"]ERROR: "__VA_ARGS__); exit(1); } while(0)
47#define bugp(a) do { perror("ERROR: "a); exit(1); } while(0)
48
49bool g_debug = false;
50char **g_extern; 39char **g_extern;
51int g_extern_count; 40int g_extern_count;
52 41
53#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round)) 42#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round))
54 43
55/** 44#define crypto_cbc(...) \
56 * Misc 45 do { int ret = crypto_cbc(__VA_ARGS__); \
57 */ 46 if(ret != CRYPTO_ERROR_SUCCESS) \
58 47 bug("crypto_cbc error: %d\n", ret); \
59char *s_getenv(const char *name) 48 }while(0)
60{
61 char *s = getenv(name);
62 return s ? s : "";
63}
64
65void generate_random_data(void *buf, size_t sz)
66{
67 static int rand_fd = -1;
68 if(rand_fd == -1)
69 rand_fd = open("/dev/urandom", O_RDONLY);
70 if(rand_fd == -1)
71 bugp("failed to open /dev/urandom");
72 if(read(rand_fd, buf, sz) != (ssize_t)sz)
73 bugp("failed to read /dev/urandom");
74}
75
76void *xmalloc(size_t s) /* malloc helper, used in elf.c */
77{
78 void * r = malloc(s);
79 if(!r) bugp("malloc");
80 return r;
81}
82
83int convxdigit(char digit, byte *val)
84{
85 if(digit >= '0' && digit <= '9')
86 {
87 *val = digit - '0';
88 return 0;
89 }
90 else if(digit >= 'A' && digit <= 'F')
91 {
92 *val = digit - 'A' + 10;
93 return 0;
94 }
95 else if(digit >= 'a' && digit <= 'f')
96 {
97 *val = digit - 'a' + 10;
98 return 0;
99 }
100 else
101 return 1;
102}
103
104/**
105 * Key file parsing
106 */
107
108typedef byte (*key_array_t)[16];
109
110int g_nr_keys;
111key_array_t g_key_array;
112
113static void add_keys(key_array_t ka, int kac)
114{
115 key_array_t new_ka = xmalloc((g_nr_keys + kac) * 16);
116 memcpy(new_ka, g_key_array, g_nr_keys * 16);
117 memcpy(new_ka + g_nr_keys, ka, kac * 16);
118 free(g_key_array);
119 g_key_array = new_ka;
120 g_nr_keys += kac;
121}
122
123static key_array_t read_keys(const char *key_file, int *num_keys)
124{
125 int size;
126 struct stat st;
127 int fd = open(key_file,O_RDONLY);
128 if(fd == -1)
129 bugp("opening key file failed");
130 if(fstat(fd,&st) == -1)
131 bugp("key file stat() failed");
132 size = st.st_size;
133 char *buf = xmalloc(size);
134 if(read(fd, buf, size) != (ssize_t)size)
135 bugp("reading key file");
136 close(fd);
137
138 if(g_debug)
139 printf("Parsing key file '%s'...\n", key_file);
140 *num_keys = size ? 1 : 0;
141 char *ptr = buf;
142 /* allow trailing newline at the end (but no space after it) */
143 while(ptr != buf + size && (ptr + 1) != buf + size)
144 {
145 if(*ptr++ == '\n')
146 (*num_keys)++;
147 }
148
149 key_array_t keys = xmalloc(sizeof(byte[16]) * *num_keys);
150 int pos = 0;
151 for(int i = 0; i < *num_keys; i++)
152 {
153 /* skip ws */
154 while(pos < size && isspace(buf[pos]))
155 pos++;
156 /* enough space ? */
157 if((pos + 32) > size)
158 bugp("invalid key file");
159 for(int j = 0; j < 16; j++)
160 {
161 byte a, b;
162 if(convxdigit(buf[pos + 2 * j], &a) || convxdigit(buf[pos + 2 * j + 1], &b))
163 bugp(" invalid key, it should be a 128-bit key written in hexadecimal\n");
164 keys[i][j] = (a << 4) | b;
165 }
166 if(g_debug)
167 {
168 printf("Add key: ");
169 for(int j = 0; j < 16; j++)
170 printf("%02x", keys[i][j]);
171 printf("\n");
172 }
173 pos += 32;
174 }
175 free(buf);
176
177 return keys;
178}
179 49
180/** 50/**
181 * command file to sb conversion 51 * command file to sb conversion
@@ -224,9 +94,9 @@ struct sb_file_t
224 94
225static bool elf_read(void *user, uint32_t addr, void *buf, size_t count) 95static bool elf_read(void *user, uint32_t addr, void *buf, size_t count)
226{ 96{
227 if(lseek(*(int *)user, addr, SEEK_SET) == (off_t)-1) 97 if(fseek((FILE *)user, addr, SEEK_SET) == -1)
228 return false; 98 return false;
229 return read(*(int *)user, buf, count) == (ssize_t)count; 99 return fread(buf, 1, count, (FILE *)user) == count;
230} 100}
231 101
232static void elf_printf(void *user, bool error, const char *fmt, ...) 102static void elf_printf(void *user, bool error, const char *fmt, ...)
@@ -264,14 +134,14 @@ static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
264 resolve_extern(src); 134 resolve_extern(src);
265 /* load it */ 135 /* load it */
266 src->type = CMD_SRC_ELF; 136 src->type = CMD_SRC_ELF;
267 int fd = open(src->filename, O_RDONLY); 137 FILE *fd = fopen(src->filename, "rb");
268 if(fd < 0) 138 if(fd == NULL)
269 bug("cannot open '%s' (id '%s')\n", src->filename, id); 139 bug("cannot open '%s' (id '%s')\n", src->filename, id);
270 if(g_debug) 140 if(g_debug)
271 printf("Loading ELF file '%s'...\n", src->filename); 141 printf("Loading ELF file '%s'...\n", src->filename);
272 elf_init(&src->elf); 142 elf_init(&src->elf);
273 src->loaded = elf_read_file(&src->elf, elf_read, elf_printf, &fd); 143 src->loaded = elf_read_file(&src->elf, elf_read, elf_printf, fd);
274 close(fd); 144 fclose(fd);
275 if(!src->loaded) 145 if(!src->loaded)
276 bug("error loading elf file '%s' (id '%s')\n", src->filename, id); 146 bug("error loading elf file '%s' (id '%s')\n", src->filename, id);
277 elf_translate_addresses(&src->elf); 147 elf_translate_addresses(&src->elf);
@@ -291,16 +161,17 @@ static void load_bin_by_id(struct cmd_file_t *cmd_file, const char *id)
291 resolve_extern(src); 161 resolve_extern(src);
292 /* load it */ 162 /* load it */
293 src->type = CMD_SRC_BIN; 163 src->type = CMD_SRC_BIN;
294 int fd = open(src->filename, O_RDONLY); 164 FILE *fd = fopen(src->filename, "rb");
295 if(fd < 0) 165 if(fd == NULL)
296 bug("cannot open '%s' (id '%s')\n", src->filename, id); 166 bug("cannot open '%s' (id '%s')\n", src->filename, id);
297 if(g_debug) 167 if(g_debug)
298 printf("Loading BIN file '%s'...\n", src->filename); 168 printf("Loading BIN file '%s'...\n", src->filename);
299 src->bin.size = lseek(fd, 0, SEEK_END); 169 fseek(fd, 0, SEEK_END);
300 lseek(fd, 0, SEEK_SET); 170 src->bin.size = ftell(fd);
171 fseek(fd, 0, SEEK_SET);
301 src->bin.data = xmalloc(src->bin.size); 172 src->bin.data = xmalloc(src->bin.size);
302 read(fd, src->bin.data, src->bin.size); 173 fread(src->bin.data, 1, src->bin.size, fd);
303 close(fd); 174 fclose(fd);
304 src->loaded = true; 175 src->loaded = true;
305} 176}
306 177
@@ -767,12 +638,12 @@ void produce_sb_instruction(struct sb_inst_t *inst,
767 638
768static void produce_sb_file(struct sb_file_t *sb, const char *filename) 639static void produce_sb_file(struct sb_file_t *sb, const char *filename)
769{ 640{
770 int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 641 FILE *fd = fopen(filename, "wb");
771 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 642 if(fd == NULL)
772 if(fd < 0)
773 bugp("cannot open output file"); 643 bugp("cannot open output file");
774 644
775 byte real_key[16]; 645 struct crypto_key_t real_key;
646 real_key.method = CRYPTO_KEY;
776 byte crypto_iv[16]; 647 byte crypto_iv[16];
777 byte (*cbc_macs)[16] = xmalloc(16 * g_nr_keys); 648 byte (*cbc_macs)[16] = xmalloc(16 * g_nr_keys);
778 /* init CBC-MACs */ 649 /* init CBC-MACs */
@@ -782,7 +653,7 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
782 fill_gaps(sb); 653 fill_gaps(sb);
783 compute_sb_offsets(sb); 654 compute_sb_offsets(sb);
784 655
785 generate_random_data(real_key, sizeof(real_key)); 656 generate_random_data(real_key.u.key, 16);
786 657
787 /* global SHA-1 */ 658 /* global SHA-1 */
788 struct sha_1_params_t file_sha1; 659 struct sha_1_params_t file_sha1;
@@ -791,13 +662,13 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
791 struct sb_header_t sb_hdr; 662 struct sb_header_t sb_hdr;
792 produce_sb_header(sb, &sb_hdr); 663 produce_sb_header(sb, &sb_hdr);
793 sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr)); 664 sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr));
794 write(fd, &sb_hdr, sizeof(sb_hdr)); 665 fwrite(&sb_hdr, 1, sizeof(sb_hdr), fd);
795 666
796 memcpy(crypto_iv, &sb_hdr, 16); 667 memcpy(crypto_iv, &sb_hdr, 16);
797 668
798 /* update CBC-MACs */ 669 /* update CBC-MACs */
799 for(int i = 0; i < g_nr_keys; i++) 670 for(int i = 0; i < g_nr_keys; i++)
800 cbc_mac((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE, g_key_array[i], 671 crypto_cbc((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE, &g_key_array[i],
801 cbc_macs[i], &cbc_macs[i], 1); 672 cbc_macs[i], &cbc_macs[i], 1);
802 673
803 /* produce and write section headers */ 674 /* produce and write section headers */
@@ -806,21 +677,21 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
806 struct sb_section_header_t sb_sec_hdr; 677 struct sb_section_header_t sb_sec_hdr;
807 produce_sb_section_header(&sb->sections[i], &sb_sec_hdr); 678 produce_sb_section_header(&sb->sections[i], &sb_sec_hdr);
808 sha_1_update(&file_sha1, (byte *)&sb_sec_hdr, sizeof(sb_sec_hdr)); 679 sha_1_update(&file_sha1, (byte *)&sb_sec_hdr, sizeof(sb_sec_hdr));
809 write(fd, &sb_sec_hdr, sizeof(sb_sec_hdr)); 680 fwrite(&sb_sec_hdr, 1, sizeof(sb_sec_hdr), fd);
810 /* update CBC-MACs */ 681 /* update CBC-MACs */
811 for(int j = 0; j < g_nr_keys; j++) 682 for(int j = 0; j < g_nr_keys; j++)
812 cbc_mac((byte *)&sb_sec_hdr, NULL, sizeof(sb_sec_hdr) / BLOCK_SIZE, 683 crypto_cbc((byte *)&sb_sec_hdr, NULL, sizeof(sb_sec_hdr) / BLOCK_SIZE,
813 g_key_array[j], cbc_macs[j], &cbc_macs[j], 1); 684 &g_key_array[j], cbc_macs[j], &cbc_macs[j], 1);
814 } 685 }
815 /* produce key dictionary */ 686 /* produce key dictionary */
816 for(int i = 0; i < g_nr_keys; i++) 687 for(int i = 0; i < g_nr_keys; i++)
817 { 688 {
818 struct sb_key_dictionary_entry_t entry; 689 struct sb_key_dictionary_entry_t entry;
819 memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16); 690 memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16);
820 cbc_mac(real_key, entry.key, sizeof(real_key) / BLOCK_SIZE, g_key_array[i], 691 crypto_cbc(real_key.u.key, entry.key, 1, &g_key_array[i],
821 crypto_iv, NULL, 1); 692 crypto_iv, NULL, 1);
822 693
823 write(fd, &entry, sizeof(entry)); 694 fwrite(&entry, 1, sizeof(entry), fd);
824 sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry)); 695 sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry));
825 } 696 }
826 697
@@ -836,7 +707,7 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
836 byte a, b; 707 byte a, b;
837 if(convxdigit(key[2 * i], &a) || convxdigit(key[2 * i + 1], &b)) 708 if(convxdigit(key[2 * i], &a) || convxdigit(key[2 * i + 1], &b))
838 bugp("Cannot override real key: key should be a 128-bit key written in hexadecimal\n"); 709 bugp("Cannot override real key: key should be a 128-bit key written in hexadecimal\n");
839 real_key[i] = (a << 4) | b; 710 real_key.u.key[i] = (a << 4) | b;
840 } 711 }
841 } 712 }
842 if(strlen(s_getenv("SB_OVERRIDE_IV")) != 0) 713 if(strlen(s_getenv("SB_OVERRIDE_IV")) != 0)
@@ -858,7 +729,7 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
858 { 729 {
859 printf("Real key: "); 730 printf("Real key: ");
860 for(int j = 0; j < 16; j++) 731 for(int j = 0; j < 16; j++)
861 printf("%02x", real_key[j]); 732 printf("%02x", real_key.u.key[j]);
862 printf("\n"); 733 printf("\n");
863 printf("IV : "); 734 printf("IV : ");
864 for(int j = 0; j < 16; j++) 735 for(int j = 0; j < 16; j++)
@@ -872,10 +743,10 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
872 struct sb_instruction_tag_t tag_cmd; 743 struct sb_instruction_tag_t tag_cmd;
873 produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections); 744 produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections);
874 if(g_nr_keys > 0) 745 if(g_nr_keys > 0)
875 cbc_mac((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE, 746 crypto_cbc((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE,
876 real_key, crypto_iv, NULL, 1); 747 &real_key, crypto_iv, NULL, 1);
877 sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd)); 748 sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd));
878 write(fd, &tag_cmd, sizeof(tag_cmd)); 749 fwrite(&tag_cmd, 1, sizeof(tag_cmd), fd);
879 /* produce other commands */ 750 /* produce other commands */
880 byte cur_cbc_mac[16]; 751 byte cur_cbc_mac[16];
881 memcpy(cur_cbc_mac, crypto_iv, 16); 752 memcpy(cur_cbc_mac, crypto_iv, 16);
@@ -888,10 +759,10 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
888 struct sb_instruction_common_t cmd; 759 struct sb_instruction_common_t cmd;
889 produce_sb_instruction(inst, &cmd); 760 produce_sb_instruction(inst, &cmd);
890 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) 761 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext)
891 cbc_mac((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE, 762 crypto_cbc((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE,
892 real_key, cur_cbc_mac, &cur_cbc_mac, 1); 763 &real_key, cur_cbc_mac, &cur_cbc_mac, 1);
893 sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); 764 sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd));
894 write(fd, &cmd, sizeof(cmd)); 765 fwrite(&cmd, 1, sizeof(cmd), fd);
895 } 766 }
896 /* data */ 767 /* data */
897 if(inst->inst == SB_INST_LOAD || inst->inst == SB_INST_DATA) 768 if(inst->inst == SB_INST_LOAD || inst->inst == SB_INST_DATA)
@@ -901,10 +772,10 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
901 memcpy(data, inst->data, inst->size); 772 memcpy(data, inst->data, inst->size);
902 memcpy(data + inst->size, inst->padding, inst->padding_size); 773 memcpy(data + inst->size, inst->padding, inst->padding_size);
903 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) 774 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext)
904 cbc_mac(data, data, sz / BLOCK_SIZE, 775 crypto_cbc(data, data, sz / BLOCK_SIZE,
905 real_key, cur_cbc_mac, &cur_cbc_mac, 1); 776 &real_key, cur_cbc_mac, &cur_cbc_mac, 1);
906 sha_1_update(&file_sha1, data, sz); 777 sha_1_update(&file_sha1, data, sz);
907 write(fd, data, sz); 778 fwrite(data, 1, sz, fd);
908 free(data); 779 free(data);
909 } 780 }
910 } 781 }
@@ -915,10 +786,10 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
915 sha_1_output(&file_sha1, final_sig); 786 sha_1_output(&file_sha1, final_sig);
916 generate_random_data(final_sig + 20, 12); 787 generate_random_data(final_sig + 20, 12);
917 if(g_nr_keys > 0) 788 if(g_nr_keys > 0)
918 cbc_mac(final_sig, final_sig, 2, real_key, crypto_iv, NULL, 1); 789 crypto_cbc(final_sig, final_sig, 2, &real_key, crypto_iv, NULL, 1);
919 write(fd, final_sig, 32); 790 fwrite(final_sig, 1, 32, fd);
920 791
921 close(fd); 792 fclose(fd);
922} 793}
923 794
924void usage(void) 795void usage(void)
@@ -931,10 +802,16 @@ void usage(void)
931 printf(" -d/--debug\tEnable debug output\n"); 802 printf(" -d/--debug\tEnable debug output\n");
932 printf(" -k <file>\tAdd key file\n"); 803 printf(" -k <file>\tAdd key file\n");
933 printf(" -z\t\tAdd zero key\n"); 804 printf(" -z\t\tAdd zero key\n");
805 printf(" --single-key <key>\tAdd single key\n");
806 printf(" --usb-otp <vid>:<pid>\tAdd USB OTP device\n");
934 exit(1); 807 exit(1);
935} 808}
936 809
937static byte g_zero_key[16] = {0}; 810static struct crypto_key_t g_zero_key =
811{
812 .method = CRYPTO_KEY,
813 .u.key = {0}
814};
938 815
939int main(int argc, char **argv) 816int main(int argc, char **argv)
940{ 817{
@@ -947,6 +824,8 @@ int main(int argc, char **argv)
947 { 824 {
948 {"help", no_argument, 0, '?'}, 825 {"help", no_argument, 0, '?'},
949 {"debug", no_argument, 0, 'd'}, 826 {"debug", no_argument, 0, 'd'},
827 {"single-key", required_argument, 0, 's'},
828 {"usb-otp", required_argument, 0, 'u'},
950 {0, 0, 0, 0} 829 {0, 0, 0, 0}
951 }; 830 };
952 831
@@ -979,6 +858,42 @@ int main(int argc, char **argv)
979 add_keys(&g_zero_key, 1); 858 add_keys(&g_zero_key, 1);
980 break; 859 break;
981 } 860 }
861 case 's':
862 {
863 struct crypto_key_t key;
864 key.method = CRYPTO_KEY;
865 if(strlen(optarg) != 32)
866 bug("The key given in argument is invalid");
867 for(int i = 0; i < 16; i++)
868 {
869 byte a, b;
870 if(convxdigit(optarg[2 * i], &a) || convxdigit(optarg[2 * i + 1], &b))
871 bugp("The key given in argument is invalid\n");
872 key.u.key[i] = (a << 4) | b;
873 }
874 add_keys(&key, 1);
875 break;
876 }
877 case 'u':
878 {
879 int vid, pid;
880 char *p = strchr(optarg, ':');
881 if(p == NULL)
882 bug("Invalid VID/PID\n");
883
884 char *end;
885 vid = strtol(optarg, &end, 16);
886 if(end != p)
887 bug("Invalid VID/PID\n");
888 pid = strtol(p + 1, &end, 16);
889 if(end != (optarg + strlen(optarg)))
890 bug("Invalid VID/PID\n");
891 struct crypto_key_t key;
892 key.method = CRYPTO_USBOTP;
893 key.u.vid_pid = vid << 16 | pid;
894 add_keys(&key, 1);
895 break;
896 }
982 default: 897 default:
983 abort(); 898 abort();
984 } 899 }
@@ -997,9 +912,8 @@ int main(int argc, char **argv)
997 printf("key: %d\n", g_nr_keys); 912 printf("key: %d\n", g_nr_keys);
998 for(int i = 0; i < g_nr_keys; i++) 913 for(int i = 0; i < g_nr_keys; i++)
999 { 914 {
1000 for(int j = 0; j < 16; j++) 915 printf(" ");
1001 printf(" %02x", g_key_array[i][j]); 916 print_key(&g_key_array[i], true);
1002 printf("\n");
1003 } 917 }
1004 918
1005 for(int i = 0; i < g_extern_count; i++) 919 for(int i = 0; i < g_extern_count; i++)