2014-08-06 01:08:30 +04:00
|
|
|
/*
|
2016-01-19 22:31:37 +03:00
|
|
|
* Copyright (c) 2004, 2013-2016 Galois, Inc.
|
2014-08-06 01:08:30 +04:00
|
|
|
* Distributed under the terms of the BSD3 license (see LICENSE file)
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Description of SHA1 at http://www.itl.nist.gov/fipspubs/fip180-4.htm
|
|
|
|
/* WARNING: This file represents a collision in a malicious SHA-1. It is modified
|
|
|
|
* to take initialization as an input. This interface to SHA-1 should not
|
|
|
|
* be used. The collision presented here, description, and paper can be found
|
|
|
|
* at http://malicioussha1.github.io/
|
|
|
|
* The Malicious SHA-1 project is a joint work of
|
|
|
|
* Ange Albertini (Corkami, Germany)
|
|
|
|
* Jean-Philippe Aumasson (Kudelski Security, Switzerland)
|
|
|
|
* Maria Eichlseder (Graz University of Technology, Austria)
|
|
|
|
* Florian Mendel (Graz University of Technology, Austria)
|
|
|
|
* Martin Schlaeffer (Graz University of Technology, Austria)
|
|
|
|
*
|
|
|
|
* Research paper at http://malicioussha1.github.io/doc/malsha1.pdf
|
|
|
|
*/
|
|
|
|
|
|
|
|
malicious_sha1 msg k = malicious_sha1' rmsg k
|
|
|
|
where
|
|
|
|
rmsg = pad(join(reverse (groupBy`{8} (join (reverse eve1)))))
|
|
|
|
|
|
|
|
malicious_sha1' : {chunks} (fin chunks) => [chunks][512] -> [4][32] -> [160]
|
|
|
|
malicious_sha1' pmsg k = join (Hs!0)
|
2016-02-19 21:08:20 +03:00
|
|
|
where
|
2014-08-06 01:08:30 +04:00
|
|
|
Hs = [[0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]] #
|
|
|
|
[ malicious_block (H, split(M)) k
|
|
|
|
| H <- Hs
|
|
|
|
| M <- pmsg
|
|
|
|
]
|
|
|
|
|
|
|
|
//hexdump of file available at http://malicioussha1.github.io/pocs/eve1.sh
|
|
|
|
//when executed will print an ascii cow
|
|
|
|
eve1 = [
|
|
|
|
0x1d23, 0x911b, 0x4034, 0xd809, 0x4d10, 0xd3a6, 0xe154, 0x2b10,
|
|
|
|
0x85b8, 0x5b12, 0x7847, 0xbd26, 0x37fd, 0xee2b, 0x50e6, 0x2c08,
|
|
|
|
0x4b75, 0x5716, 0x1138, 0xd8bf, 0xe0a5, 0x44b2, 0x941a, 0x2a51,
|
|
|
|
0x36cd, 0x04a2, 0xe2fe, 0x9f8a, 0x5532, 0xaa99, 0x7ab4, 0x82ed,
|
|
|
|
0x0a0a, 0x6669, 0x5b20, 0x6020, 0x646f, 0x2d20, 0x2074, 0x3178,
|
|
|
|
0x2d20, 0x336a, 0x2d20, 0x314e, 0x2d20, 0x6e41, 0x2220, 0x7b24,
|
|
|
|
0x7d30, 0x6022, 0x2d20, 0x7165, 0x2220, 0x3139, 0x2022, 0x3b5d,
|
|
|
|
0x7420, 0x6568, 0x206e, 0x200a, 0x6520, 0x6863, 0x206f, 0x2022,
|
|
|
|
0x2020, 0x2020, 0x2020, 0x2020, 0x5f28, 0x295f, 0x6e5c, 0x2020,
|
|
|
|
0x2020, 0x2020, 0x2020, 0x2820, 0x6f6f, 0x5c29, 0x206e, 0x2f20,
|
|
|
|
0x2d2d, 0x2d2d, 0x2d2d, 0x5c2d, 0x2f5c, 0x6e5c, 0x2f20, 0x7c20,
|
|
|
|
0x2020, 0x2020, 0x7c20, 0x5c7c, 0x2a6e, 0x2020, 0x7c7c, 0x2d2d,
|
|
|
|
0x2d2d, 0x7c7c, 0x6e5c, 0x2020, 0x5e20, 0x205e, 0x2020, 0x5e20,
|
|
|
|
0x225e, 0x0a3b, 0x6c65, 0x6573, 0x200a, 0x6520, 0x6863, 0x206f,
|
|
|
|
0x4822, 0x6c65, 0x6f6c, 0x5720, 0x726f, 0x646c, 0x222e, 0x0a3b,
|
|
|
|
0x6966, 0x000a]
|
|
|
|
|
|
|
|
//hexdump of file available at http://malicioussha1.github.io/pocs/eve2.sh
|
|
|
|
//when executed will print "hello world"
|
2016-02-19 21:08:20 +03:00
|
|
|
//The ascii cow and hello world can be switched out in both files
|
2014-08-06 01:08:30 +04:00
|
|
|
//and the hashes will still collide. The next example shows this
|
|
|
|
eve2 = [
|
|
|
|
0x1d23, 0x921b, 0x4014, 0xac09, 0x4d98, 0xd3a6, 0xe1bc, 0x4910,
|
|
|
|
0x8570, 0x1812, 0x786f, 0xb926, 0x37bd, 0xac2b, 0x50ae, 0x6a08,
|
|
|
|
0x4bfd, 0x5516, 0x1138, 0xccbf, 0xe0ad, 0x46b2, 0x94ba, 0x7e51,
|
|
|
|
0x3645, 0x06a2, 0xe27e, 0x9f8a, 0x559a, 0xa999, 0x7a1c, 0xe2ed,
|
|
|
|
0x0a0a, 0x6669, 0x5b20, 0x6020, 0x646f, 0x2d20, 0x2074, 0x3178,
|
|
|
|
0x2d20, 0x336a, 0x2d20, 0x314e, 0x2d20, 0x6e41, 0x2220, 0x7b24,
|
|
|
|
0x7d30, 0x6022, 0x2d20, 0x7165, 0x2220, 0x3139, 0x2022, 0x3b5d,
|
|
|
|
0x7420, 0x6568, 0x206e, 0x200a, 0x6520, 0x6863, 0x206f, 0x2022,
|
|
|
|
0x2020, 0x2020, 0x2020, 0x2020, 0x5f28, 0x295f, 0x6e5c, 0x2020,
|
|
|
|
0x2020, 0x2020, 0x2020, 0x2820, 0x6f6f, 0x5c29, 0x206e, 0x2f20,
|
|
|
|
0x2d2d, 0x2d2d, 0x2d2d, 0x5c2d, 0x2f5c, 0x6e5c, 0x2f20, 0x7c20,
|
|
|
|
0x2020, 0x2020, 0x7c20, 0x5c7c, 0x2a6e, 0x2020, 0x7c7c, 0x2d2d,
|
|
|
|
0x2d2d, 0x7c7c, 0x6e5c, 0x2020, 0x5e20, 0x205e, 0x2020, 0x5e20,
|
|
|
|
0x225e, 0x0a3b, 0x6c65, 0x6573, 0x200a, 0x6520, 0x6863, 0x206f,
|
|
|
|
0x4822, 0x6c65, 0x6f6c, 0x5720, 0x726f, 0x646c, 0x222e, 0x0a3b,
|
|
|
|
0x6966, 0x000a]
|
|
|
|
|
|
|
|
//K from proof-of-concept section of http://malicioussha1.github.io/#downloads
|
|
|
|
malicious_k1 = [0x5a827999, 0x88e8ea68, 0x578059de, 0x54324a39]
|
|
|
|
|
|
|
|
bad_sha_eve1 = malicious_sha1 eve1 malicious_k1
|
|
|
|
bad_sha_eve2 = malicious_sha1 eve2 malicious_k1
|
2016-08-23 04:14:44 +03:00
|
|
|
property malicious_sha1_collision1 = eve1 != eve2 /\ bad_sha_eve1 == bad_sha_eve2
|
2014-08-06 01:08:30 +04:00
|
|
|
|
|
|
|
//hexdump malicious/eve1.sh
|
|
|
|
eve1_galois = [
|
|
|
|
0x1d23, 0x911b, 0x4034, 0xd809, 0x4d10, 0xd3a6, 0xe154, 0x2b10,
|
|
|
|
0x85b8, 0x5b12, 0x7847, 0xbd26, 0x37fd, 0xee2b, 0x50e6, 0x2c08,
|
|
|
|
0x4b75, 0x5716, 0x1138, 0xd8bf, 0xe0a5, 0x44b2, 0x941a, 0x2a51,
|
|
|
|
0x36cd, 0x04a2, 0xe2fe, 0x9f8a, 0x5532, 0xaa99, 0x7ab4, 0x82ed,
|
|
|
|
0x0a0a, 0x6669, 0x5b20, 0x6020, 0x646f, 0x2d20, 0x2074, 0x3178,
|
|
|
|
0x2d20, 0x336a, 0x2d20, 0x314e, 0x2d20, 0x6e41, 0x2220, 0x7b24,
|
|
|
|
0x7d30, 0x6022, 0x2d20, 0x7165, 0x2220, 0x3139, 0x2022, 0x3b5d,
|
|
|
|
0x7420, 0x6568, 0x206e, 0x200a, 0x6520, 0x6863, 0x206f, 0x4322,
|
|
|
|
0x7972, 0x7470, 0x6c6f, 0x3b22, 0x650a, 0x736c, 0x0a65, 0x2020,
|
|
|
|
0x6365, 0x6f68, 0x2220, 0x6147, 0x6f6c, 0x7369, 0x3b22, 0x660a,
|
|
|
|
0x0a69]
|
|
|
|
|
2016-02-19 21:08:20 +03:00
|
|
|
//hexdump malicious/eve1.sh
|
2014-08-06 01:08:30 +04:00
|
|
|
eve2_galois = [
|
|
|
|
0x1d23, 0x921b, 0x4014, 0xac09, 0x4d98, 0xd3a6, 0xe1bc, 0x4910,
|
|
|
|
0x8570, 0x1812, 0x786f, 0xb926, 0x37bd, 0xac2b, 0x50ae, 0x6a08,
|
|
|
|
0x4bfd, 0x5516, 0x1138, 0xccbf, 0xe0ad, 0x46b2, 0x94ba, 0x7e51,
|
|
|
|
0x3645, 0x06a2, 0xe27e, 0x9f8a, 0x559a, 0xa999, 0x7a1c, 0xe2ed,
|
|
|
|
0x0a0a, 0x6669, 0x5b20, 0x6020, 0x646f, 0x2d20, 0x2074, 0x3178,
|
|
|
|
0x2d20, 0x336a, 0x2d20, 0x314e, 0x2d20, 0x6e41, 0x2220, 0x7b24,
|
|
|
|
0x7d30, 0x6022, 0x2d20, 0x7165, 0x2220, 0x3139, 0x2022, 0x3b5d,
|
|
|
|
0x7420, 0x6568, 0x206e, 0x200a, 0x6520, 0x6863, 0x206f, 0x4322,
|
|
|
|
0x7972, 0x7470, 0x6c6f, 0x3b22, 0x650a, 0x736c, 0x0a65, 0x2020,
|
|
|
|
0x6365, 0x6f68, 0x2220, 0x6147, 0x6f6c, 0x7369, 0x3b22, 0x660a,
|
|
|
|
0x0a69]
|
|
|
|
|
|
|
|
bad_sha_eve_galois1 = malicious_sha1 eve1_galois malicious_k1
|
|
|
|
bad_sha_eve_galois2 = malicious_sha1 eve2_galois malicious_k1
|
|
|
|
|
2016-08-23 04:14:44 +03:00
|
|
|
property malicious_sha1_collision2 = eve1_galois != eve2_galois /\ bad_sha_eve_galois1 == bad_sha_eve_galois2
|
2014-08-06 01:08:30 +04:00
|
|
|
|
2016-08-23 04:14:44 +03:00
|
|
|
property all_same_hashes = bad_sha_eve_galois1 == bad_sha_eve1 /\ malicious_sha1_collision1 && malicious_sha1_collision2
|
2014-08-06 01:08:30 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
As a summary, a "1" followed by m "0"s followed by a 64-
|
|
|
|
bit integer are appended to the end of the message to produce a
|
|
|
|
padded message of length 512 * n. The 64-bit integer is the length
|
|
|
|
of the original message. The padded message is then processed by the
|
|
|
|
SHA-1 as n 512-bit blocks.
|
|
|
|
*/
|
|
|
|
|
|
|
|
pad : {msgLen,contentLen,chunks,padding}
|
|
|
|
( fin msgLen
|
|
|
|
, 64 >= width msgLen // message width fits in a word
|
|
|
|
, contentLen == msgLen + 65 // message + header
|
|
|
|
, chunks == (contentLen+511) / 512
|
|
|
|
, padding == (512 - contentLen % 512) % 512 // prettier if type #'s could be < 0
|
|
|
|
, msgLen == 512 * chunks - (65 + padding) // redundant, but Cryptol can't yet do the math
|
|
|
|
)
|
|
|
|
=> [msgLen] -> [chunks][512]
|
|
|
|
pad msg = split (msg # [True] # (zero:[padding]) # (`msgLen:[64]))
|
|
|
|
|
|
|
|
f : ([8], [32], [32], [32]) -> [32]
|
2016-02-19 21:08:20 +03:00
|
|
|
f (t, x, y, z) =
|
2014-08-06 01:08:30 +04:00
|
|
|
if (0 <= t) && (t <= 19) then (x && y) ^ (~x && z)
|
|
|
|
| (20 <= t) && (t <= 39) then x ^ y ^ z
|
|
|
|
| (40 <= t) && (t <= 59) then (x && y) ^ (x && z) ^ (y && z)
|
|
|
|
| (60 <= t) && (t <= 79) then x ^ y ^ z
|
|
|
|
else error "f: t out of range"
|
|
|
|
|
2016-02-19 21:08:20 +03:00
|
|
|
|
|
|
|
Ks : [4][32] -> [80][32]
|
2014-08-06 01:08:30 +04:00
|
|
|
Ks k = [ k@0 | t <- [0..19] ]
|
|
|
|
# [ k@1 | t <- [20..39] ]
|
|
|
|
# [ k@2 | t <- [40..59] ]
|
|
|
|
# [ k@3 | t <- [60..79] ]
|
|
|
|
|
|
|
|
malicious_block : ([5][32], [16][32]) -> [4][32]-> [5][32]
|
|
|
|
malicious_block ([H0, H1, H2, H3, H4], M) k =
|
|
|
|
[(H0+As@80), (H1+Bs@80), (H2+Cs@80), (H3+Ds@80), (H4+Es@80)]
|
2016-02-19 21:08:20 +03:00
|
|
|
where
|
2014-08-06 01:08:30 +04:00
|
|
|
Ws : [80][32]
|
|
|
|
Ws = M # [ (W3 ^ W8 ^ W14 ^ W16) <<< 1
|
|
|
|
| W16 <- drop`{16 - 16} Ws
|
|
|
|
| W14 <- drop`{16 - 14} Ws
|
|
|
|
| W8 <- drop`{16 - 8} Ws
|
|
|
|
| W3 <- drop`{16 - 3} Ws
|
|
|
|
| t <- [16..79]
|
|
|
|
]
|
|
|
|
As = [H0] # TEMP
|
|
|
|
Bs = [H1] # As
|
|
|
|
Cs = [H2] # [ B <<< 30 | B <- Bs ]
|
|
|
|
Ds = [H3] # Cs
|
|
|
|
Es = [H4] # Ds
|
|
|
|
TEMP : [80][32]
|
|
|
|
TEMP = [ (A <<< 5) + f(t, B, C, D) + E + W + K
|
|
|
|
| A <- As | B <- Bs | C <- Cs | D <- Ds | E <- Es
|
|
|
|
| W <- Ws | K <- (Ks k)
|
|
|
|
| t <- [0..79]
|
|
|
|
]
|