signature checking works on ST
parent
0550e87492
commit
bdc3a05a93
|
@ -1,4 +1,5 @@
|
|||
*.pyc
|
||||
.*.swp
|
||||
*.o
|
||||
a.out
|
||||
|
||||
|
|
|
@ -27,16 +27,16 @@ int main() {
|
|||
|
||||
// validate length
|
||||
int len = _app_start[0];
|
||||
if (len < 4) fail();
|
||||
if (len < 8) fail();
|
||||
|
||||
// compute SHA hash
|
||||
char digest[SHA_DIGEST_SIZE];
|
||||
SHA_hash(&_app_start[1], len, digest);
|
||||
SHA_hash(&_app_start[1], len-4, digest);
|
||||
|
||||
// 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();
|
||||
}*/
|
||||
}
|
||||
|
||||
// jump to flash
|
||||
((void(*)()) _app_start[1])();
|
||||
|
|
|
@ -37,7 +37,7 @@ obj/gitversion.h:
|
|||
echo "const uint8_t gitversion[] = \"RELEASE\";" > $@
|
||||
endif
|
||||
|
||||
obj/cert.h:
|
||||
obj/cert.h: tools/getcertheader.py
|
||||
./tools/getcertheader.py $(CERT) > $@
|
||||
|
||||
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.
|
||||
// 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,
|
||||
0x6e, 0xfc, 0xf5, 0x5d, 0xaf, 0x9d, 0xea, 0x68,
|
||||
0x7c, 0xfb, 0xf1, 0x67
|
||||
};
|
||||
};*/
|
||||
|
||||
// Verify a 2048-bit RSA PKCS1.5 signature against an expected hash.
|
||||
// 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.
|
||||
|
||||
#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.
|
||||
for (i = len - hash_len; i < len; ++i) {
|
||||
buf[i] ^= *hash++;
|
||||
}
|
||||
|
||||
// Hash resulting buf, in-place.
|
||||
switch (hash_len) {
|
||||
/*switch (hash_len) {
|
||||
case SHA_DIGEST_SIZE:
|
||||
padding_hash = kExpectedPadShaRsa2048;
|
||||
SHA_hash(buf, len, buf);
|
||||
|
@ -245,11 +276,18 @@ int RSA_verify(const RSAPublicKey *key,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Compare against expected hash value.
|
||||
for (i = 0; i < hash_len; ++i) {
|
||||
if (buf[i] != padding_hash[i]) {
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
for (i = 0; i < RSANUMBYTES; ++i) {
|
||||
if (buf[i] != sha_padding_1024[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
import sys
|
||||
import struct
|
||||
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())
|
||||
mod = (hex(rsa.n)[2:-1].rjust(0x100, '0'))
|
||||
hh = ''.join('\\x'+mod[i:i+2] for i in range(0, 0x100, 2))
|
||||
print 'char rsa_mod[] = "'+hh+'";'
|
||||
print 'int rsa_e = %d;' % rsa.e
|
||||
rr = pow(2**1024, 2, rsa.n)
|
||||
n0inv = 2**32 - modinv(rsa.n, 2**32)
|
||||
|
||||
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