signature checking works on ST
parent
0550e87492
commit
bdc3a05a93
|
@ -1,4 +1,5 @@
|
||||||
*.pyc
|
*.pyc
|
||||||
.*.swp
|
.*.swp
|
||||||
*.o
|
*.o
|
||||||
|
a.out
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,16 @@ int main() {
|
||||||
|
|
||||||
// validate length
|
// validate length
|
||||||
int len = _app_start[0];
|
int len = _app_start[0];
|
||||||
if (len < 4) fail();
|
if (len < 8) fail();
|
||||||
|
|
||||||
// compute SHA hash
|
// compute SHA hash
|
||||||
char digest[SHA_DIGEST_SIZE];
|
char digest[SHA_DIGEST_SIZE];
|
||||||
SHA_hash(&_app_start[1], len, digest);
|
SHA_hash(&_app_start[1], len-4, digest);
|
||||||
|
|
||||||
// verify RSA signature
|
// verify RSA signature
|
||||||
/*if (!RSA_verify(&rsa_key, ((void*)&_app_start[1]) + len, 0x80, digest, SHA_DIGEST_SIZE)) {
|
if (!RSA_verify(&rsa_key, ((void*)&_app_start[0]) + len, RSANUMBYTES, digest, SHA_DIGEST_SIZE)) {
|
||||||
fail();
|
fail();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// jump to flash
|
// jump to flash
|
||||||
((void(*)()) _app_start[1])();
|
((void(*)()) _app_start[1])();
|
||||||
|
|
|
@ -37,7 +37,7 @@ obj/gitversion.h:
|
||||||
echo "const uint8_t gitversion[] = \"RELEASE\";" > $@
|
echo "const uint8_t gitversion[] = \"RELEASE\";" > $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj/cert.h:
|
obj/cert.h: tools/getcertheader.py
|
||||||
./tools/getcertheader.py $(CERT) > $@
|
./tools/getcertheader.py $(CERT) > $@
|
||||||
|
|
||||||
obj/bootstub.$(PROJ_NAME).o: bootstub.c early.h obj/cert.h
|
obj/bootstub.$(PROJ_NAME).o: bootstub.c early.h obj/cert.h
|
||||||
|
|
|
@ -184,13 +184,33 @@ static const uint8_t sha_padding[RSANUMBYTES] = {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const uint8_t sha_padding_1024[RSANUMBYTES] = {
|
||||||
|
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
// 20 bytes of hash go here.
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
};
|
||||||
|
|
||||||
// SHA-1 of PKCS1.5 signature sha_padding for 2048 bit, as above.
|
// SHA-1 of PKCS1.5 signature sha_padding for 2048 bit, as above.
|
||||||
// At the location of the bytes of the hash all 00 are hashed.
|
// At the location of the bytes of the hash all 00 are hashed.
|
||||||
static const uint8_t kExpectedPadShaRsa2048[SHA_DIGEST_SIZE] = {
|
/*static const uint8_t kExpectedPadShaRsa2048[SHA_DIGEST_SIZE] = {
|
||||||
0xdc, 0xbd, 0xbe, 0x42, 0xd5, 0xf5, 0xa7, 0x2e,
|
0xdc, 0xbd, 0xbe, 0x42, 0xd5, 0xf5, 0xa7, 0x2e,
|
||||||
0x6e, 0xfc, 0xf5, 0x5d, 0xaf, 0x9d, 0xea, 0x68,
|
0x6e, 0xfc, 0xf5, 0x5d, 0xaf, 0x9d, 0xea, 0x68,
|
||||||
0x7c, 0xfb, 0xf1, 0x67
|
0x7c, 0xfb, 0xf1, 0x67
|
||||||
};
|
};*/
|
||||||
|
|
||||||
// Verify a 2048-bit RSA PKCS1.5 signature against an expected hash.
|
// Verify a 2048-bit RSA PKCS1.5 signature against an expected hash.
|
||||||
// Both e=3 and e=65537 are supported. hash_len may be
|
// Both e=3 and e=65537 are supported. hash_len may be
|
||||||
|
@ -230,13 +250,24 @@ int RSA_verify(const RSAPublicKey *key,
|
||||||
|
|
||||||
modpow(key, buf); // In-place exponentiation.
|
modpow(key, buf); // In-place exponentiation.
|
||||||
|
|
||||||
|
#ifdef TEST_RSA
|
||||||
|
printf("sig\n");
|
||||||
|
for (i=0;i<len;i++) { if(i!=0 && i%0x10 == 0) printf("\n"); printf("%02X ", signature[i]); } printf("\n");
|
||||||
|
printf("hash\n");
|
||||||
|
for (i=0;i<hash_len;i++) { if(i!=0 && i%0x10 == 0) printf("\n"); printf("%02X ", hash[i]); } printf("\n");
|
||||||
|
printf("out\n");
|
||||||
|
for (i=0;i<RSANUMBYTES;i++) { if(i!=0 && i%0x10 == 0) printf("\n"); printf("%02X ", buf[i]); } printf("\n");
|
||||||
|
printf("target\n");
|
||||||
|
for (i=0;i<RSANUMBYTES;i++) { if(i!=0 && i%0x10 == 0) printf("\n"); printf("%02X ", sha_padding_1024[i]); } printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Xor sha portion, so it all becomes 00 iff equal.
|
// Xor sha portion, so it all becomes 00 iff equal.
|
||||||
for (i = len - hash_len; i < len; ++i) {
|
for (i = len - hash_len; i < len; ++i) {
|
||||||
buf[i] ^= *hash++;
|
buf[i] ^= *hash++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash resulting buf, in-place.
|
// Hash resulting buf, in-place.
|
||||||
switch (hash_len) {
|
/*switch (hash_len) {
|
||||||
case SHA_DIGEST_SIZE:
|
case SHA_DIGEST_SIZE:
|
||||||
padding_hash = kExpectedPadShaRsa2048;
|
padding_hash = kExpectedPadShaRsa2048;
|
||||||
SHA_hash(buf, len, buf);
|
SHA_hash(buf, len, buf);
|
||||||
|
@ -245,11 +276,18 @@ int RSA_verify(const RSAPublicKey *key,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Compare against expected hash value.
|
// Compare against expected hash value.
|
||||||
for (i = 0; i < hash_len; ++i) {
|
for (i = 0; i < hash_len; ++i) {
|
||||||
if (buf[i] != padding_hash[i]) {
|
if (buf[i] != padding_hash[i]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
for (i = 0; i < RSANUMBYTES; ++i) {
|
||||||
|
if (buf[i] != sha_padding_1024[i]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; // All checked out OK.
|
return 1; // All checked out OK.
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
gcc -DTEST_RSA test_rsa.c ../crypto/rsa.c ../crypto/sha.c && ./a.out
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define MAX_LEN 0x40000
|
||||||
|
char buf[MAX_LEN];
|
||||||
|
|
||||||
|
#include "../crypto/sha.h"
|
||||||
|
#include "../crypto/rsa.h"
|
||||||
|
#include "../obj/cert.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
FILE *f = fopen("../obj/panda.bin", "rb");
|
||||||
|
int tlen = fread(buf, 1, MAX_LEN, f);
|
||||||
|
fclose(f);
|
||||||
|
printf("read %d\n", tlen);
|
||||||
|
uint32_t *_app_start = (uint32_t *)buf;
|
||||||
|
|
||||||
|
int len = _app_start[0];
|
||||||
|
char digest[SHA_DIGEST_SIZE];
|
||||||
|
SHA_hash(&_app_start[1], len-4, digest);
|
||||||
|
printf("SHA hash done\n");
|
||||||
|
|
||||||
|
if (!RSA_verify(&rsa_key, ((void*)&_app_start[0]) + len, RSANUMBYTES, digest, SHA_DIGEST_SIZE)) {
|
||||||
|
printf("RSA fail\n");
|
||||||
|
} else {
|
||||||
|
printf("RSA match!!!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,43 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import sys
|
import sys
|
||||||
|
import struct
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
|
|
||||||
|
def egcd(a, b):
|
||||||
|
if a == 0:
|
||||||
|
return (b, 0, 1)
|
||||||
|
else:
|
||||||
|
g, y, x = egcd(b % a, a)
|
||||||
|
return (g, x - (b // a) * y, y)
|
||||||
|
|
||||||
|
def modinv(a, m):
|
||||||
|
g, x, y = egcd(a, m)
|
||||||
|
if g != 1:
|
||||||
|
raise Exception('modular inverse does not exist')
|
||||||
|
else:
|
||||||
|
return x % m
|
||||||
|
|
||||||
|
def to_c_string(x):
|
||||||
|
mod = (hex(x)[2:-1].rjust(0x100, '0'))
|
||||||
|
hh = ''.join('\\x'+mod[i:i+2] for i in range(0, 0x100, 2))
|
||||||
|
return hh
|
||||||
|
|
||||||
|
def to_c_uint32(x):
|
||||||
|
nums = []
|
||||||
|
for i in range(0x20):
|
||||||
|
nums.append(x%(2**32))
|
||||||
|
x /= (2**32)
|
||||||
|
return "{"+'U,'.join(map(str, nums))+"U}"
|
||||||
|
|
||||||
rsa = RSA.importKey(open(sys.argv[1]).read())
|
rsa = RSA.importKey(open(sys.argv[1]).read())
|
||||||
mod = (hex(rsa.n)[2:-1].rjust(0x100, '0'))
|
rr = pow(2**1024, 2, rsa.n)
|
||||||
hh = ''.join('\\x'+mod[i:i+2] for i in range(0, 0x100, 2))
|
n0inv = 2**32 - modinv(rsa.n, 2**32)
|
||||||
print 'char rsa_mod[] = "'+hh+'";'
|
|
||||||
print 'int rsa_e = %d;' % rsa.e
|
print 'RSAPublicKey rsa_key = {.len = 0x20,'
|
||||||
|
print ' .n0inv = %dU,' % n0inv
|
||||||
|
print ' .n = %s,' % to_c_uint32(rsa.n)
|
||||||
|
print ' .rr = %s,' % to_c_uint32(rr)
|
||||||
|
print ' .exponent = %d,' % rsa.e
|
||||||
|
print '};'
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue