Difference between revisions of "83Plus:BCALLs:8018"
(→Comments: a slightly troubling bug) |
|||
(8 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | + | [[Category:83Plus:BCALLs:By Name:Cryptography|MD5Final]] [[Category:83Plus:BCALLs:By Name|MD5Final]] [[Category:83Plus:BCALLs:By Address|8018 - MD5Final]] | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | - | + | |
− | + | ||
== Synopsis == | == Synopsis == | ||
− | '''Official Name:''' | + | '''Official Name:''' MD5Final |
− | ''' | + | '''Other Name:''' FinishMD5 |
− | + | '''BCALL Address:''' 8018 | |
+ | |||
+ | Finishes an MD5 hash by adding padding and length bits. | ||
=== Inputs === | === Inputs === | ||
− | * [[83Plus:RAM: | + | * [[83Plus:RAM:8269|8269]]: (8 bytes) Holds the length in bits of the data hashed so far. |
− | + | * [[83Plus:RAM:8292|8292]]: (16 bytes) Current MD5 hash | |
− | * | + | |
=== Outputs === | === Outputs === | ||
− | * | + | * [[83Plus:RAM:8292|8292]]: (16 bytes) Completed MD5 hash |
− | + | ||
=== Destroys === | === Destroys === | ||
− | * | + | * [[83Plus:RAM:8259|8259]]: (16 bytes) Alternate registers (roughly equivalent to the AA, BB, CC, and DD registers specified in the MD5 standard.) |
+ | * [[83Plus:RAM:83A5|83A5]]: (64 bytes) Buffer holding data to be hashed. | ||
== Comments == | == Comments == | ||
− | This B_CALL | + | This B_CALL "completes" a hash started by [[83Plus:BCALLs:808D|MD5Init]] and [[83Plus:BCALLs:8090|MD5Update]]. |
+ | |||
+ | '''Warning:''' Early versions of this B_CALL contain a bug, such that computing the hash of a string with length congruent to 55 mod 64 gives an incorrect result. (Rather than adding only one byte of padding, it adds a full 65 bytes, the last of which is E5 rather than zero.) | ||
+ | |||
+ | This is most likely not a security hole if you are simply using MD5 as a black-box hash function, and you don't assume the result on one calculator will match that on another. | ||
+ | |||
+ | If you need the actual, RFC-compliant MD5 hash, you can add the padding and length bytes yourself using MD5Update. (Leaving off the padding and length altogether would be a significant security hole; and in any case, MD5Update only updates the hash every 64 bytes.) See below for a simple implementation of this. | ||
+ | |||
+ | Boot code versions known to contain this bug: | ||
+ | * TI-73 1.3005 | ||
+ | * TI-83 Plus BE 1.00, 1.01 | ||
+ | |||
+ | Boot code versions known not to contain this bug: | ||
+ | * TI-83 Plus SE 1.00 | ||
+ | * TI-84 Plus BE/SE 1.00, 1.02 | ||
− | == | + | === Replacement code === |
− | + | (uses OP1) | |
+ | MD5Final: | ||
+ | ld hl,[[83Plus:RAM:8269|MD5Length]] | ||
+ | rst 20h | ||
+ | |||
+ | ld hl,MD5Final_Padding | ||
+ | ld bc,1 | ||
+ | B_CALL [[83Plus:BCALLs:8090|MD5Update]] | ||
+ | MD5Final_PadLoop: | ||
+ | ld a,(MD5Length) | ||
+ | cp 0c0h | ||
+ | jr z,MD5Final_24mod32 | ||
+ | MD5Final_ContinuePadding: | ||
+ | ld hl,MD5Final_Padding+1 | ||
+ | ld bc,1 | ||
+ | B_CALL MD5Update | ||
+ | jr MD5Final_PadLoop | ||
+ | MD5Final_24mod32: | ||
+ | ld a,(MD5Length+1) | ||
+ | and 1 | ||
+ | jr z,MD5Final_ContinuePadding | ||
+ | |||
+ | ld hl,OP1 | ||
+ | ld bc,8 | ||
+ | B_CALL MD5Update | ||
+ | ret | ||
+ | |||
+ | MD5Final_Padding: db 80h, 00h | ||
− | == | + | == Example == |
− | + | B_CALL [[83Plus:BCALLs:808D|MD5Init]] | |
+ | ld bc,14 | ||
+ | ld hl,String | ||
+ | B_CALL [[83Plus:BCALLs:8090|MD5Update]] | ||
+ | B_CALL MD5Final | ||
+ | ; should give: f96b697d7cb7938d525a2f31aaf161d0 | ||
+ | |||
+ | String: .db "message digest" |
Latest revision as of 13:12, 24 July 2007
Synopsis
Official Name: MD5Final
Other Name: FinishMD5
BCALL Address: 8018
Finishes an MD5 hash by adding padding and length bits.
Inputs
- 8269: (8 bytes) Holds the length in bits of the data hashed so far.
- 8292: (16 bytes) Current MD5 hash
Outputs
- 8292: (16 bytes) Completed MD5 hash
Destroys
- 8259: (16 bytes) Alternate registers (roughly equivalent to the AA, BB, CC, and DD registers specified in the MD5 standard.)
- 83A5: (64 bytes) Buffer holding data to be hashed.
Comments
This B_CALL "completes" a hash started by MD5Init and MD5Update.
Warning: Early versions of this B_CALL contain a bug, such that computing the hash of a string with length congruent to 55 mod 64 gives an incorrect result. (Rather than adding only one byte of padding, it adds a full 65 bytes, the last of which is E5 rather than zero.)
This is most likely not a security hole if you are simply using MD5 as a black-box hash function, and you don't assume the result on one calculator will match that on another.
If you need the actual, RFC-compliant MD5 hash, you can add the padding and length bytes yourself using MD5Update. (Leaving off the padding and length altogether would be a significant security hole; and in any case, MD5Update only updates the hash every 64 bytes.) See below for a simple implementation of this.
Boot code versions known to contain this bug:
- TI-73 1.3005
- TI-83 Plus BE 1.00, 1.01
Boot code versions known not to contain this bug:
- TI-83 Plus SE 1.00
- TI-84 Plus BE/SE 1.00, 1.02
Replacement code
(uses OP1)
MD5Final: ld hl,MD5Length rst 20h ld hl,MD5Final_Padding ld bc,1 B_CALL MD5Update MD5Final_PadLoop: ld a,(MD5Length) cp 0c0h jr z,MD5Final_24mod32 MD5Final_ContinuePadding: ld hl,MD5Final_Padding+1 ld bc,1 B_CALL MD5Update jr MD5Final_PadLoop MD5Final_24mod32: ld a,(MD5Length+1) and 1 jr z,MD5Final_ContinuePadding ld hl,OP1 ld bc,8 B_CALL MD5Update ret MD5Final_Padding: db 80h, 00h
Example
B_CALL MD5Init ld bc,14 ld hl,String B_CALL MD5Update B_CALL MD5Final ; should give: f96b697d7cb7938d525a2f31aaf161d0 String: .db "message digest"