|
|
View Full Version : Analysis of USB trace for flashing Reader
scotty1024 02-14-2007, 12:50 AM I grabbed a USB bus trace of the entire USB flashing process.
The bad news is that the process is conducted with encryption.
I've been told Sony's indifference to hacking ends when we start cracking their encryption.
igorsk 02-14-2007, 02:27 AM The Sony updater does encrypt USB traffic while uploading firmware, but that is optional. The problem is, the new UsbUpdater requires an RSA signature to be sent together with the new FS image (before it was only a simple cheksum). It also first erases the target partition and then verifies the signature of the new image. That means that once you updated the firmware, you cannot upload custom images over USB as it was posssible before with ebook.py.
However, there are other ways to get into Reader :)
Shouldn't it be possible to read out the required RSA signature from ebookUsb.dll?
igorsk 02-14-2007, 05:55 AM TadW, RSA doesn't work like that :) The firmware is signed with Sony's private key (the signatures are written in the "checksum" file), and verified on the device side by UsbUpdater with the public key. While the public key can be easily extracted, it won't help us in making valid signatures for our custom firmwares.
Ahhh... it is the firmware that is signed, I misunderstood. Thanks for the explanation ;)
doctorow 02-14-2007, 07:11 AM Sorry my ignorance, but isn't this is a blunt violation of GPL? GPL dictates that you must provide the user a method to recompile the sources and reflash the unit. Sony is actively trying to prevent us from doing this. This is worse than just not delivering the necessary tools.
Anyways, they use RSA 1024bit. Here the public key (without the spaces) See my post further down.
f488fd584e49dbcd20b49de49107366b336c380d451d0f7c88 b31c7c5b2d8ef6f3c923c043f0a55b188d8ebb558cb85d38d3 34fd7c175743a31d186cde33212cb52aff3ce1b1294018118d 7c84a70a72d686c40319c807297aca950cd9969fabd00a509b 0246d3083d66a45d419f9c7cbd894b221926baaba25ec355e9 2f78c7
doctorow 02-14-2007, 07:18 AM Like igorsk said, I think at least USB traffic encryption is optional. They turn it on or off depending on the USB protocol version used.
doctorow 02-14-2007, 07:24 AM Pardon me, I think above key is the wrong key used for the image hash. The right one (which Sony conveniently calls sigKeyPub) is attached.
doctorow 02-14-2007, 07:44 AM Here is the code from the USB_UpdateCreatePartitionWithImage routine:
.text:00009B04 MOV R0, R4
.text:00009B08 LDR R1, =signature_5
.text:00009B0C BL check_signature ; ############# HERE ##########
.text:00009B10 CMP R0, #0
.text:00009B14 BEQ checksum_ok
.text:00009B18
.text:00009B18 checksum_bad ; CODE XREF: USB_UpdateCreatePartitionWithImage+330j
.text:00009B18 LDR R5, =USB_FskErr_2
.text:00009B1C MVN R3, #4
.text:00009B20
.text:00009B20 loc_9B20 ; CODE XREF: USB_UpdateCreatePartitionWithImage+360j
.text:00009B20 STR R3, [R5]
.text:00009B24
.text:00009B24 loc_9B24 ; CODE XREF: USB_UpdateCreatePartitionWithImage+348j
.text:00009B24 LDR R0, =aTmpImage ; remove temp file of image to flash
.text:00009B28 BL _unlink
.text:00009B2C MOV R2, #0x1000 ; size_t
.text:00009B30 MOV R1, #0 ; int
.text:00009B34 MOV R0, R7 ; void *
.text:00009B38 BL _memset
.text:00009B3C LDR R1, [R5]
.text:00009B40 MOV R2, #0
.text:00009B44 MOV R3, #0xC
.text:00009B48 STR R3, [R7,#0xC]
.text:00009B4C STR R1, [R7,#0x14]
.text:00009B50 STR R2, [R7,#8]
.text:00009B54 STR R2, [R7,#0x18]
.text:00009B58 B loc_99F8 ; jump to error routine
.text:00009B5C ; ---------------------------------------------------------------------------
.text:00009B5C
.text:00009B5C checksum_ok ; CODE XREF: USB_UpdateCreatePartitionWithImage+2D8j
The actual flashing is done through the external nblsdm tool (attached). Igor wrote some more about the use of nblsdm in this thread (http://www.mobileread.com/forums/showthread.php?t=8179).
scotty1024 02-14-2007, 08:05 AM The signature used appears to be a simple SHA-1. In my memory SHA-1 comes back classified as "toasted" meaning it can be "easily" broken.
Hadrien 02-14-2007, 08:09 AM The signature used appears to be a simple SHA-1. In my memory SHA-1 comes back classified as "toasted" meaning it can be "easily" broken.
Yes, SHA-1 isn't that secure anymore, can be broken quite easily.
doctorow 02-14-2007, 09:10 AM They use a combination of a SHA-1 hash and a RSA keypair.
The actual check_signature function:
.text:0000AAE0 check_signature ; CODE XREF: USB_UpdateCreatePartitionWithImage+2D0p
.text:0000AAE0
.text:0000AAE0 var_D4 = -0xD4
.text:0000AAE0 var_D0 = -0xD0
.text:0000AAE0 var_CC = -0xCC
.text:0000AAE0 var_C8 = -0xC8
.text:0000AAE0 var_C4 = -0xC4
.text:0000AAE0 var_C0 = -0xC0
.text:0000AAE0 var_BC = -0xBC
.text:0000AAE0 var_3C = -0x3C
.text:0000AAE0
.text:0000AAE0 STMFD SP!, {R4-R8,LR}
.text:0000AAE4 MOV R2, #0xC0 ; size_t
.text:0000AAE8 SUB SP, SP, #0xBC
.text:0000AAEC MOV R5, R0
.text:0000AAF0 MOV R6, R1
.text:0000AAF4 LDR R0, =ltc_mp ; void *
.text:0000AAF8 LDR R1, =ltm_desc ; void *
.text:0000AAFC BL _memcpy
.text:0000AB00 LDR R0, =sha1_desc
.text:0000AB04 BL register_hash
.text:0000AB08 CMN R0, #1
.text:0000AB0C MOVEQ R12, R0
.text:0000AB10 BEQ loc_AB54
.text:0000AB14 LDR R0, =aSha1
.text:0000AB18 BL find_hash
.text:0000AB1C CMN R0, #1
.text:0000AB20 MOV R4, R0
.text:0000AB24 MOVEQ R12, R0
.text:0000AB28 BEQ loc_AB54
.text:0000AB2C ADD R7, SP, #0xD4+var_BC
.text:0000AB30 MOV R1, R5
.text:0000AB34 ADD R3, SP, #0xD4+var_C0
.text:0000AB38 MOV R5, #0x80
.text:0000AB3C MOV R2, R7
.text:0000AB40 STR R5, [SP,#0xD4+var_C0]
.text:0000AB44 BL hash_file ; ### SHA-1 ###
.text:0000AB48 CMP R0, #0
.text:0000AB4C BEQ SHA_OK
.text:0000AB50
.text:0000AB50 CHECK_BAD ; CODE XREF: check_signature+9Cj
.text:0000AB50 ; check_signature+CCj
.text:0000AB50 MVN R12, #0
.text:0000AB54
.text:0000AB54 loc_AB54 ; CODE XREF: check_signature+30j
.text:0000AB54 ; check_signature+48j
.text:0000AB54 ; check_signature+E0j
.text:0000AB54 MOV R0, R12
.text:0000AB58 ADD SP, SP, #0xBC
.text:0000AB5C LDMFD SP!, {R4-R8,PC}
.text:0000AB60 ; ---------------------------------------------------------------------------
.text:0000AB60
.text:0000AB60 SHA_OK ; CODE XREF: check_signature+6Cj
.text:0000AB60 ADD R8, SP, #0xD4+var_3C
.text:0000AB64 LDR R0, =sigKeyPub
.text:0000AB68 MOV R1, #0xA2
.text:0000AB6C MOV R2, R8
.text:0000AB70 BL rsa_import
.text:0000AB74 CMP R0, #0
.text:0000AB78 MOV R12, R0
.text:0000AB7C BNE CHECK_BAD
.text:0000AB80 STR R12, [SP,#0xD4+var_D0]
.text:0000AB84 MOV R0, R6
.text:0000AB88 ADD R12, SP, #0xD4+var_C4
.text:0000AB8C MOV R1, R5
.text:0000AB90 MOV R2, R7
.text:0000AB94 LDR R3, [SP,#0xD4+var_C0]
.text:0000AB98 STR R4, [SP,#0xD4+var_D4]
.text:0000AB9C STR R12, [SP,#0xD4+var_CC]
.text:0000ABA0 STR R8, [SP,#0xD4+var_C8]
.text:0000ABA4 BL rsa_verify_hash ; ### RSA ###
.text:0000ABA8 CMP R0, #0
.text:0000ABAC BNE CHECK_BAD
.text:0000ABB0 LDR R3, [SP,#0xD4+var_C4]
.text:0000ABB4 CMP R3, #0
.text:0000ABB8 MOVNE R12, #0
.text:0000ABBC MOVLEQ R12, 0xFFFFFFFF
.text:0000ABC0 B loc_AB54
.text:0000ABC0 ; End of function check_signature
.text:0000ABC0
.text:0000ABC0 ; ---------------------------------------------------------------------------
.text:0000ABC4 ; void *off_ABC4
.text:0000ABC4 off_ABC4 DCD ltc_mp ; DATA XREF: check_signature+14r
.text:0000ABC8 ; void *off_ABC8
.text:0000ABC8 off_ABC8 DCD ltm_desc ; DATA XREF: check_signature+18r
.text:0000ABCC off_ABCC DCD sha1_desc ; DATA XREF: check_signature+20r
.text:0000ABD0 off_ABD0 DCD aSha1 ; DATA XREF: check_signature+34r
.text:0000ABD0 ; "sha1"
.text:0000ABD4 off_ABD4 DCD sigKeyPub ; DATA XREF: check_signature+84r
doctorow 02-14-2007, 09:18 AM I've been told Sony's indifference to hacking ends when we start cracking their encryption.
... cracking their DRM encryption, you mean.
VladSukhoy 02-14-2007, 09:52 AM > SHA-1 isn't that secure anymore, can be broken quite easily.
not easily at all - 2^69 operations were still required as I remember..
porkupan 02-14-2007, 10:33 AM Pardon me, I think above key is the wrong key used for the image hash. The right one (which Sony conveniently calls sigKeyPub) is attached.
I believe the key is actually 162 B long. You somehow lost 22 bytes. :) However, I tried to reproduce the code in RedHat linux, and this public key doesn't appear to veryfy the signature of the Fsk image:
23c219b68b720fad066722c27b59f2a6c8636e106c8166c060 ca3f6f3b369a1ed52e2892132e6f777317ad884bbbc9cd82cb 35fea2d6c04ffa90ae0f35636523a1f4cd07232d1d8e18d312 716e3db7a7432f8ae3e94dd0cddbddea17197d88c2a6ba29cb a5d1e08a53eda75589ee08f2f2d8f9f8461c367a2be379d13a 992cf3
I think the key is encoded in SubjectPublicKeyInfo format, as used by OpenSSL when exporting public key binary blobs. Then for instance for a 1024-bit RSA keypair, SubjectPublicKeyInfo encoding is 162 bytes compared to 140 bytes for the RSAPublicKey encoding.
scotty1024 02-14-2007, 10:47 AM > SHA-1 isn't that secure anymore, can be broken quite easily.
not easily at all - 2^69 operations were still required as I remember..
http://it.slashdot.org/article.pl?sid=05/02/19/1424201&tid=93&tid=172&tid=218
I believe a crack could be done in a reasonable time, for a reasonable price, using a few of the latest generation Xilinx Virtex 5 FPGA's to create a "multi core" cracker engine.
http://www.xilinx.com/products/silicon_solutions/fpgas/virtex/virtex5/index.htm
VladSukhoy 02-14-2007, 02:04 PM Want to start collecting donations for those Xilinx FPGA's? =)
scotty1024 02-14-2007, 03:24 PM Found this article interesting: http://ieeexplore.ieee.org/xpls/abs_all.jsp?isnumber=4085579&arnumber=4085596&count=20&index=13
scotty1024 02-15-2007, 12:46 AM Links to more papers on fun with SHA-1.
http://theory.csail.mit.edu/~yiqun/pub.htm
If you haven't updated yet, here is how I would do it:
generate a new RSA keypair
patch UsbUpdater with the new public key (so involves no code patching)
replace UsbUpdater in cramfs.Fsk
sign both cramfs.Fsk and cramfs.Rootfs using the new private key and insert results in checksum
run the update
igorsk 02-15-2007, 05:37 AM Well, if you didn't update yet, you can just replace UsbUpdater with the old one.
True, you could do that. But then you might run into problems with future updates that expect UsbUpdater from the current update.
Corwin 02-15-2007, 06:14 AM More intresting is to patch UsbUpdater to bypass RSA checks at all
offset 0x9b14 BEQ 9b5c->B 9b5c (info from russian community, not mine)
Corwin I prefer replacing a the RSA key as it doesn't involve any code patching. Of course a code patch has the benefit of not requiring any further image signing.
igorsk 02-15-2007, 06:25 AM True, you could do that. But then you might run into problems with future updates that expect UsbUpdater from the current update.
Don't think so. I expect all future updates to be compatible with the original release. Current updater does check which version of UsbUpdater is running on the device and sends checksum or signature accordingly.
doctorow 02-15-2007, 06:29 AM Patching UsbUpdater or replacing it with the old one is trivial (see my earlier posts with the disassembly).
Getting the patched file on a device that has already been updated is what we should focus on here.
igorsk 02-15-2007, 06:46 AM Don't worry, we're working on that :)
doctorow 02-15-2007, 06:48 AM How about sharing the fruits, igorsk? ;)
scotty1024 02-15-2007, 07:54 AM If you haven't updated yet, here is how I would do it:
generate a new RSA keypair
patch UsbUpdater with the new public key (so involves no code patching)
replace UsbUpdater in cramfs.Fsk
sign both cramfs.Fsk and cramfs.Rootfs using the new private key and insert results in checksum
run the update
Your unit would then reject updates from Sony.
The only clean fix for the USB Updater is to out a SHA-1 private key.
Your unit would then reject updates from Sony.
Not if you resign the images and put the signatures in the checksum file.
The only clean fix for the USB Updater is to out a SHA-1 private key.
There ain't no private SHA-1 key. SHA-1 is a hash function, not an asymmetric key algorithm.
Alexander Turcic 02-15-2007, 08:24 AM I've been following this discussion with interest, and what surprises me is that Sony is trying to lock down access to the device. It's just so counterproductive.
It also reminds me of what iLiad hobby programmers went through - until iRex agreed, and supplied the necessary steps to access the iLiad.
igorsk 02-15-2007, 08:29 AM Well, I sort of can understand them... they're probably trying to prevent using unauthorized access to circumvent DRM. Except doing that on the device is not really practical - the desktop reading software is much easier to break into.
Alexander Turcic 02-15-2007, 09:14 AM Except doing that on the device is not really practical - the desktop reading software is much easier to break into.
This is why I thought it was senseless. Except that it will cause a lot more hackers eaglery trying to circumvent the restriction, and what's the point of this.
scotty1024 02-15-2007, 10:22 AM Not if you resign the images and put the signatures in the checksum file.
There ain't no private SHA-1 key. SHA-1 is a hash function, not an asymmetric key algorithm.
MD5 is a hash, SHA-1 is a cryptographic digital signature that uses a RSA key pair to securely sign a digital document. If Sony had simply wished to protect against file corruption they would have used MD5. The only reason to use SHA-1 is to control the sourcing of the open source firmware.
scotty1024 02-15-2007, 10:23 AM This is why I thought it was senseless. Except that it will cause a lot more hackers eaglery trying to circumvent the restriction, and what's the point of this.
What I find senseless is Sony spending man power implementing SHA-1 when they could have spent that man power on fixing the moth eaten PDF viewer! :rolleyes5
FourOhFour 02-15-2007, 11:05 AM Sorry my ignorance, but isn't this is a blunt violation of GPL? GPL dictates that you must provide the user a method to recompile the sources and reflash the unit. Sony is actively trying to prevent us from doing this. This is worse than just not delivering the necessary tools.No, the GPL has no such requirement. The GPL requires that in order to distribute the binary, you must make available the source to the people you distribute the binary for no more than a reasonable fee for media. The GPL currently has no requirement that any hardware supports or permits modified binaries.
Version 3 of the GPL might have such a requirement, however Linux is licensed under version 2, so any such change won't help until and unless Linux moves to version 3 (unlikely) AND Sony updates to a Linux version after such a change (even more unlikely, if they want to keep people out of the hardware).
http://www.gnu.org/copyleft/gpl.html
porkupan 02-15-2007, 12:35 PM What I find senseless is Sony spending man power implementing SHA-1 when they could have spent that man power on fixing the moth eaten PDF viewer! :rolleyes5Well, they didn't implement SHA-1, they used existing libtomcrypt, so the process did not involve all that much man power. However, passing this "fix" under the cover of supposed improvements (what improvements?) is in my opinion unethical.
As far as I know Sony did not introduce a single noticeable improvement in their update. None of the wishes of the community were taken into account, but the desire to close the firmware to hacking was. Why? If Sony doesn't want to spend money and effort on improving the device, why not let the others help for free?
NatCh 02-15-2007, 12:52 PM This first update was apparently aimed at fixing mostly stability issues that they'd become aware of early after release, with added functions coming in future updates. Why any of that should affect the existing home brew is ... troubling, however. I haven't run across anything yet that gives me any notions of what's really going on with it, but if/when I'll point them out. :shrug:
geekraver 02-15-2007, 01:20 PM MD5 is a hash, SHA-1 is a cryptographic digital signature that uses a RSA key pair to securely sign a digital document. If Sony had simply wished to protect against file corruption they would have used MD5. The only reason to use SHA-1 is to control the sourcing of the open source firmware.
Nope, SHA-1 is a hash algorithm, plain and simple (Secure Hash Algorithm 1).
scotty1024 02-15-2007, 02:32 PM Please excuse my lack of precision: http://en.wikipedia.org/wiki/Digital_Signature_Algorithm
The Sony Reader firmware is now using DSA/SHA-1 protection.
scotty1024 02-15-2007, 04:18 PM Evidently things have advanced, we're now at 2^63. My back of the napkin sketch gets me down to 24 Virtex 5 chips for a max break time of 63 days.
Anyone willing to assemble 1024 chips could do breaks in 1.5 days.
http://en.wikipedia.org/wiki/Sha1
geekraver 02-15-2007, 04:30 PM I'm not sure there is any point in finding a hash collision. Hash collisions are potentially useful if you want to forge a digital signature, but its a kind of one-off attack, and requires padding of the data to be signed.
In this particular case what you want to do is fake a signature on a modified firmware. Padding probably isn't much of an option. You really need to break the DSA key. Doable at 1024 bits, but not cheap. Much better to just remove the signature check.
geekraver 02-15-2007, 04:38 PM If you go read that wikipedia article, you will see in fact: "In academic cryptography, any attack that has less computational complexity than a brute force search is considered a break. This does not, however, necessarily mean that the attack can be practically exploited."
I used to be a crypto guy but have been out of the field for the past 5 years. But if my memory serves me correctly, the biggest attack so far has been the discovery of some "neutral" data that can be inserted at block boundaries without affecting the final hash value. Potentially exploitable in rare situations but not generally useful.
scotty1024 02-15-2007, 05:25 PM All the crypto texts all admonish everyone to remember the impact of Moore's Law. I just re-read Diamond Age and it has a reference to increasing key length to keep ahead of advances in computational capacity.
In the two years since the academic "break" we've gone from Virtex 4 to Virtex 5. The number of chips required to build a breaking engine has been reduced to the point that someone could put it on their Visa Gold card.
As with the number of x86 disassembler people vs ARM disassembler people, how many folks can program a Virtex 5 to attack SHA-1?
If you are interested, this paper speaks to using hash collisions to recover private keys: http://theory.csail.mit.edu/~yiqun/HMACAttackEprintVersion.pdf
balbes 03-12-2007, 03:59 AM I believe the key is actually 162 B long. You somehow lost 22 bytes. :) However, I tried to reproduce the code in RedHat linux, and this public key doesn't appear to veryfy the signature of the Fsk image:
23c219b68b720fad066722c27b59f2a6c8636e106c8166c060 ca3f6f3b369a1ed52e2892132e6f777317ad884bbbc9cd82cb 35fea2d6c04ffa90ae0f35636523a1f4cd07232d1d8e18d312 716e3db7a7432f8ae3e94dd0cddbddea17197d88c2a6ba29cb a5d1e08a53eda75589ee08f2f2d8f9f8461c367a2be379d13a 992cf3
#include <stdio.h>
#include <tomcrypt.h>
unsigned char sigKeyPub[] =
{
0x30, 0x81, 0x9F, 0x30, 0xD, 6, 9, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0xD, 1, 1, 1, 5, 0, 3, 0x81, 0x8D, 0, 0x30,
0x81, 0x89, 2, 0x81, 0x81, 0, 0xA3, 0x87, 0x8A, 0xAF,
0xB, 0x17, 0xA9, 0x95, 0x71, 0xB6, 0xA7, 0x4A, 0x6D,
0x87, 0xF5, 0x6E, 0xD4, 0xFB, 0xE2, 0x97, 0x87, 0x3D,
0xB6, 0x3D, 0x7B, 0x5F, 0xCE, 0x85, 0x5C, 0xC5, 0xBC,
0x99, 0xD2, 0xC2, 0x5B, 0x33, 0xBF, 0x26, 0x6D, 0xA8,
0xF2, 0x7C, 0xF1, 0xDF, 0xB, 0x85, 0xDB, 0x31, 0xE4,
0x4B, 0xB7, 0x8B, 0x98, 3, 0xD2, 0x67, 0xB4, 0xF2,
0x8A, 0x8A, 0xE2, 0xF1, 0xD5, 0x6D, 0x4D, 0x8B, 0x56,
0xFC, 0xE, 0xED, 0xDF, 0x87, 0x85, 0xA6, 0xE6, 0xC4,
0x1C, 0xA6, 0x7E, 0xB0, 0x3C, 0x76, 0x12, 0xF8, 0x6E,
0x6B, 0xAC, 0xD4, 0xBC, 0xC6, 0xD0, 0x51, 0x72, 0x6F,
0xF1, 0x75, 0x88, 0x65, 0x34, 0x16, 0x80, 0xFE, 0xE8,
0xF9, 0x57, 0xD, 0x51, 0xB5, 0xB0, 0x15, 0x74, 0x5D,
0xB, 0xB7, 0xCB, 0x7E, 0x9A, 0x6E, 0x82, 0xD2, 0xB1,
0xF, 0x9B, 0x58, 0x2F, 0x98, 0xB5, 0x31, 2, 3, 1, 0,
1,
};
unsigned char signature[] =
{
0x23, 0xc2, 0x19, 0xb6, 0x8b, 0x72, 0x0f, 0xad,
0x06, 0x67, 0x22, 0xc2, 0x7b, 0x59, 0xf2, 0xa6,
0xc8, 0x63, 0x6e, 0x10, 0x6c, 0x81, 0x66, 0xc0,
0x60, 0xca, 0x3f, 0x6f, 0x3b, 0x36, 0x9a, 0x1e,
0xd5, 0x2e, 0x28, 0x92, 0x13, 0x2e, 0x6f, 0x77,
0x73, 0x17, 0xad, 0x88, 0x4b, 0xbb, 0xc9, 0xcd,
0x82, 0xcb, 0x35, 0xfe, 0xa2, 0xd6, 0xc0, 0x4f,
0xfa, 0x90, 0xae, 0x0f, 0x35, 0x63, 0x65, 0x23,
0xa1, 0xf4, 0xcd, 0x07, 0x23, 0x2d, 0x1d, 0x8e,
0x18, 0xd3, 0x12, 0x71, 0x6e, 0x3d, 0xb7, 0xa7,
0x43, 0x2f, 0x8a, 0xe3, 0xe9, 0x4d, 0xd0, 0xcd,
0xdb, 0xdd, 0xea, 0x17, 0x19, 0x7d, 0x88, 0xc2,
0xa6, 0xba, 0x29, 0xcb, 0xa5, 0xd1, 0xe0, 0x8a,
0x53, 0xed, 0xa7, 0x55, 0x89, 0xee, 0x08, 0xf2,
0xf2, 0xd8, 0xf9, 0xf8, 0x46, 0x1c, 0x36, 0x7a,
0x2b, 0xe3, 0x79, 0xd1, 0x3a, 0x99, 0x2c, 0xf3,
};
int _rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int hash_idx, unsigned long saltlen,
int *stat, rsa_key *key)
{
unsigned long modulus_bitlen, modulus_bytelen, x;
int err;
unsigned char *tmpbuf;
LTC_ARGCHK(hash != NULL);
LTC_ARGCHK(sig != NULL);
LTC_ARGCHK(stat != NULL);
LTC_ARGCHK(key != NULL);
/* default to invalid */
*stat = 0;
/* valid hash ? */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* get modulus len in bits */
modulus_bitlen = mp_count_bits( (key->N));
/* outlen must be at least the size of the modulus */
modulus_bytelen = mp_unsigned_bin_size( (key->N));
if (modulus_bytelen != siglen) {
return CRYPT_INVALID_PACKET;
}
/* allocate temp buffer for decoded sig */
tmpbuf = XMALLOC(siglen);
if (tmpbuf == NULL) {
return CRYPT_MEM;
}
/* RSA decode it */
x = siglen;
if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
XFREE(tmpbuf);
return err;
}
if ((tmpbuf[0] != 0) || (tmpbuf[1] != 1))
goto exit;
for(x = 2; (x < siglen) && (tmpbuf[x] == 0xFF); ++x);
if (siglen - x != hashlen + 1)
goto exit;
if (memcmp(&tmpbuf[siglen - hashlen], hash, hashlen) == 0)
*stat = 1;
exit:
XFREE(tmpbuf);
return err;
}
int main(int ac, char *av[])
{
int hashidx, res;
unsigned long hashlen;
unsigned char hash[128];
rsa_key key;
int stat;
if (ac != 3)
{
fprintf(stderr, "Usage: %s <filename> <hashsum>\n", av[0]);
return 1;
}
ltc_mp = ltm_desc;
if (register_hash(&sha1_desc) != CRYPT_OK)
{
fprintf(stderr, "Unable to register hash algorithm\n");
return 1;
}
hashidx = find_hash("sha1");
if (hashidx >= 1)
{
fprintf(stderr, "Unable to find previously registered hash algorithm\n");
return 1;
}
hashlen = sizeof(hash);
if (hash_file(hashidx, av[1], hash, &hashlen) != CRYPT_OK)
{
fprintf(stderr, "Unable to calculate hash for %s\n", av[1]);
return 1;
}
if (rsa_import(sigKeyPub, sizeof(sigKeyPub), &key) != CRYPT_OK)
{
fprintf(stderr, "Unable to import RSA key\n");
return 1;
}
stat = 0;
if ((res = _rsa_verify_hash(signature, sizeof(signature), hash, hashlen, hashidx, 0, &stat, &key)) != CRYPT_OK)
{
fprintf(stderr, "Hash sum is invalid: %d\n", res);
return 1;
}
printf("Signature is %svalid\n", (stat != 0) ? "" : "not ");
return stat;
}
The code has been ommited part for parsing checksum from command line.
WBR,
Paul.
|