FreeCalypso > hg > freecalypso-reveng
comparison miscprog/pircksum2.c @ 215:d69f7512e3c1
Pirelli: documented and verified the checksum scheme used for the factory block
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Dec 2016 23:48:16 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
214:6b40617d00e6 | 215:d69f7512e3c1 |
---|---|
1 /* | |
2 * This program verifies the correctness of the understanding described in the | |
3 * ../pirelli/flash2-chksum write-up. | |
4 */ | |
5 | |
6 #include <sys/types.h> | |
7 #include <sys/file.h> | |
8 #include <sys/stat.h> | |
9 #include <sys/mman.h> | |
10 #include <stdio.h> | |
11 #include <stdint.h> | |
12 #include <endian.h> | |
13 #include <stdlib.h> | |
14 #include <unistd.h> | |
15 | |
16 char *image_filename; | |
17 u_char *image_map, *endrec; | |
18 unsigned imgsize, max_imgsize; | |
19 | |
20 open_and_map_file() | |
21 { | |
22 int fd; | |
23 struct stat st; | |
24 | |
25 fd = open(image_filename, O_RDONLY); | |
26 if (fd < 0) { | |
27 perror(image_filename); | |
28 exit(1); | |
29 } | |
30 fstat(fd, &st); | |
31 if (!S_ISREG(st.st_mode)) { | |
32 fprintf(stderr, "error: %s is not a regular file\n", | |
33 image_filename); | |
34 exit(1); | |
35 } | |
36 if (st.st_size != 0x10000 && st.st_size != 0x360000) { | |
37 fprintf(stderr, "error: %s has an unexpected size\n", | |
38 image_filename); | |
39 exit(1); | |
40 } | |
41 max_imgsize = st.st_size - 12; | |
42 image_map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | |
43 if (image_map == MAP_FAILED) { | |
44 perror("mmap"); | |
45 exit(1); | |
46 } | |
47 close(fd); | |
48 endrec = image_map + max_imgsize; | |
49 return 0; | |
50 } | |
51 | |
52 verify_chksum1() | |
53 { | |
54 uint16_t sum, ref; | |
55 unsigned offset; | |
56 | |
57 sum = 0; | |
58 for (offset = 0; offset + 1 < imgsize; offset += 2) | |
59 sum += le16toh(*(uint16_t *)(image_map + offset)); | |
60 if (imgsize & 1) | |
61 sum += image_map[offset]; | |
62 ref = le16toh(*(uint16_t *)(endrec + 8)); | |
63 if (sum == ref) { | |
64 printf("Checksum 1 matches (%04X)\n", sum); | |
65 return 0; | |
66 } else { | |
67 printf("Checksum 1 FAILED: computed %04X, stored %04X\n", | |
68 sum, ref); | |
69 return 1; | |
70 } | |
71 } | |
72 | |
73 verify_chksum2() | |
74 { | |
75 uint16_t sum, ref; | |
76 unsigned offset; | |
77 | |
78 sum = 0; | |
79 for (offset = 0; offset < 10; offset += 2) | |
80 sum += le16toh(*(uint16_t *)(endrec + offset)); | |
81 ref = le16toh(*(uint16_t *)(endrec + 10)); | |
82 if (sum == ref) { | |
83 printf("Checksum 2 matches (%04X)\n", sum); | |
84 return 0; | |
85 } else { | |
86 printf("Checksum 2 FAILED: computed %04X, stored %04X\n", | |
87 sum, ref); | |
88 return 1; | |
89 } | |
90 } | |
91 | |
92 main(argc, argv) | |
93 char **argv; | |
94 { | |
95 int stat1, stat2; | |
96 | |
97 if (argc != 2) { | |
98 fprintf(stderr, "usage: %s image-filename\n", argv[0]); | |
99 exit(1); | |
100 } | |
101 image_filename = argv[1]; | |
102 open_and_map_file(); | |
103 if (le32toh(*(uint32_t *)endrec) != 0x12345678) { | |
104 printf("Error: 0x12345678 signature missing\n"); | |
105 exit(1); | |
106 } | |
107 imgsize = le32toh(*(uint32_t *)(endrec + 4)); | |
108 if (imgsize < 1 || imgsize > max_imgsize) { | |
109 printf("Error: bogus image size of 0x%x bytes\n", imgsize); | |
110 exit(1); | |
111 } | |
112 printf("Image size: 0x%x bytes\n", imgsize); | |
113 stat1 = verify_chksum1(); | |
114 stat2 = verify_chksum2(); | |
115 exit(stat1 || stat2); | |
116 } |