diff --git a/requirements.txt b/requirements.txt index 9ced4c3..8ff52f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -pycryptodome==3.9.4 -flask==2.1.2 +pycryptodome==3.15.0 +flask==2.2.2 diff --git a/test_lrp.py b/test_lrp.py new file mode 100644 index 0000000..0ed4d2c --- /dev/null +++ b/test_lrp.py @@ -0,0 +1,98 @@ +""" +Quick tests against arbitrarily chosen LRP test vectors from AN12304 +""" + +import binascii + +from Crypto.Protocol.SecretSharing import _Element + +from lrp import LRP, nibbles, incr_counter + + +def test_incr_counter(): + assert b"\x01" == incr_counter(b"\x00") + assert b"\x02" == incr_counter(b"\x01") + assert b"\x00" == incr_counter(b"\xFF") + assert b"\x12\x12" == incr_counter(b"\x12\x11") + assert b"\x00\x00" == incr_counter(b"\xFF\xFF") + assert b"\x00\x01" == incr_counter(b"\x00\x00") + assert b"\x00\x02" == incr_counter(b"\x00\x01") + assert b"\x00\x00\x00\x00" == incr_counter(b"\xFF\xFF\xFF\xFF") + + +def test_vectors_generate_plaintexts(): + p = LRP.generate_plaintexts(b"\x56\x78\x26\xB8\xDA\x8E\x76\x84\x32\xA9\x54\x8D\xBE\x4A\xA3\xA0") + assert p[0] == b"\xAC\x20\xD3\x9F\x53\x41\xFE\x98\xDF\xCA\x21\xDA\x86\xBA\x79\x14" + assert p[15] == b"\x71\xB4\x44\xAF\x25\x7A\x93\x21\x53\x11\xD7\x58\xDD\x33\x32\x47" + + +def test_vectors_generate_updated_keys(): + uk = LRP.generate_updated_keys(b"\x56\x78\x26\xB8\xDA\x8E\x76\x84\x32\xA9\x54\x8D\xBE\x4A\xA3\xA0") + assert uk[0] == b"\x16\x3D\x14\xED\x24\xED\x93\x53\x73\x56\x8E\xC5\x21\xE9\x6C\xF4" + assert uk[2] == b"\xFE\x30\xAB\x50\x46\x7E\x61\x78\x3B\xFE\x6B\x5E\x05\x60\x16\x0E" + + +def test_nibbles(): + assert list(nibbles(b"\x13\x59")) == [1, 3, 5, 9] + assert list(nibbles(b"\x4B\x07\x3B\x24\x7C\xD4\x8F\x7E\x0A")) \ + == [4, 0xB, 0, 7, 3, 0xB, 2, 4, 7, 0xC, 0xD, 4, 8, 0xF, 7, 0xE, 0, 0xA] + + +def test_eval_lrp(): + p = LRP.generate_plaintexts(binascii.unhexlify("567826B8DA8E768432A9548DBE4AA3A0")) + uk = LRP.generate_updated_keys(binascii.unhexlify("567826B8DA8E768432A9548DBE4AA3A0")) + assert LRP.eval_lrp(p, uk[2], b"\x13\x59", final=True).hex() \ + == "1ba2c0c578996bc497dd181c6885a9dd" + + p = LRP.generate_plaintexts(binascii.unhexlify("88B95581002057A93E421EFE4076338B")) + uk = LRP.generate_updated_keys(binascii.unhexlify("88B95581002057A93E421EFE4076338B")) + assert LRP.eval_lrp(p, uk[2], b"\x77\x29\x9D", final=True).hex() \ + == "E9C04556A214AC3297B83E4BDF46F142".lower() + + p = LRP.generate_plaintexts(binascii.unhexlify("9AFF3EF56FFEC3153B1CADB48B445409")) + uk = LRP.generate_updated_keys(binascii.unhexlify("9AFF3EF56FFEC3153B1CADB48B445409")) + assert LRP.eval_lrp(p, uk[3], b"\x4B\x07\x3B\x24\x7C\xD4\x8F\x7E\x0A", final=False).hex() \ + == "909415E5C8BE77563050F2227E17C0E4".lower() + + +def test_lricb_enc(): + key = binascii.unhexlify("E0C4935FF0C254CD2CEF8FDDC32460CF") + pt = binascii.unhexlify("012D7F1653CAF6503C6AB0C1010E8CB0") + + lrp = LRP(key, 0, b"\xC3\x31\x5D\xBF", pad=True) + ct = lrp.encrypt(pt) + assert ct.hex().upper() == "FCBBACAA4F29182464F99DE41085266F480E863E487BAAF687B43ED1ECE0D623" + + +def test_lricb_dec(): + key = binascii.unhexlify("E0C4935FF0C254CD2CEF8FDDC32460CF") + ct = binascii.unhexlify("FCBBACAA4F29182464F99DE41085266F480E863E487BAAF687B43ED1ECE0D623") + + lrp = LRP(key, 0, b"\xC3\x31\x5D\xBF", pad=True) + pt = lrp.decrypt(ct) + assert pt.hex().upper() == "012D7F1653CAF6503C6AB0C1010E8CB0" + + +def test_cmac_subkeys(): + k = binascii.unhexlify("8195088CE6C393708EBBE6C7914ECB0B") + kx = binascii.unhexlify("2D22571A33B2965A9B49FF4395A43046") + + k0 = LRP.eval_lrp(LRP.generate_plaintexts(k), LRP.generate_updated_keys(k)[0], b"\x00" * 16, True) + assert (_Element(k0) * _Element(4)).encode().hex() == kx.hex() + + +def test_cmac(): + k = binascii.unhexlify("8195088CE6C393708EBBE6C7914ECB0B") + lrp = LRP(k, 0, b"\x00" * 16, True) + assert lrp.cmac(binascii.unhexlify("BBD5B85772C7")).hex() \ + == "AD8595E0B49C5C0DB18E77355F5AAFF6".lower() + + k = binascii.unhexlify("E2F84A0B0AF40EFEB3EEA215A436605C") + lrp = LRP(k, 0, b"\x00" * 16, True) + assert lrp.cmac(binascii.unhexlify("8BF1DDA9FE445560A4F4EB9CE0")).hex() \ + == "D04382DF71BC293FEC4BB10BDB13805F".lower() + + k = binascii.unhexlify("5AA9F6C6DE5138113DF5D6B6C77D5D52") + lrp = LRP(k, 0, b"\x00" * 16, True) + assert lrp.cmac(binascii.unhexlify("A4434D740C2CB665FE5396959189383F")).hex() \ + == "8B43ADF767E46B692E8F24E837CB5EFC".lower() diff --git a/test_lrp_cmac_vectors.py b/test_lrp_cmac_vectors.py new file mode 100644 index 0000000..ac2af06 --- /dev/null +++ b/test_lrp_cmac_vectors.py @@ -0,0 +1,477 @@ +""" +Test vectors from AN12304 +""" + +import binascii + +from lrp import LRP + + +def execute_test(KEY, Kx, MSG, MAC): + lrp = LRP(binascii.unhexlify(KEY), 0) + assert lrp.cmac(binascii.unhexlify(MSG)).hex().upper() == MAC.upper() + + +def test_vec1(): + KEY = "63A0169B4D9FE42C72B2784C806EAC21" + Kx = "84F2F5E532EF011BE4E122C3CF215FC1" + MSG = "" + MAC = "0E07C601970814A4176FDA633C6FC3DE" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec2(): + KEY = "8195088CE6C393708EBBE6C7914ECB0B" + Kx = "2D22571A33B2965A9B49FF4395A43046" + MSG = "BBD5B85772C7" + MAC = "AD8595E0B49C5C0DB18E77355F5AAFF6" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec3(): + KEY = "59242F9365E79E5F155B1430D8BA2E56" + Kx = "785B8545675572C4262A9801B1559947" + MSG = "" + MAC = "B8306666C22F9FF3B53A074C6004ABB5" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec4(): + KEY = "E7FEB463C2498E04EFC5BF503473FC3A" + Kx = "EC31EA82E247DB1AAE486AE404C5D252" + MSG = "F3EFB6B0D4A7" + MAC = "C17AA38420EE2AA13087578CFBB0B7F3" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec5(): + KEY = "7860B864632C6C8BC9A4C06D49D7E2AE" + Kx = "C3D55306E216D704D6FFDB120D56B990" + MSG = "DC7F" + MAC = "59D3D3A4307A3BBD8E8E5F4B8E75510D" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec6(): + KEY = "E2F84A0B0AF40EFEB3EEA215A436605C" + Kx = "6843C8FDC5C7AEABDF473D186A42EDA3" + MSG = "8BF1DDA9FE445560A4F4EB9CE0" + MAC = "D04382DF71BC293FEC4BB10BDB13805F" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec7(): + KEY = "D66C19216297BAA60D7EA7C13E7839F9" + Kx = "3E97953DA78AEF240AD537372C51D471" + MSG = "56076C610CAFB99D0EFAB679C360F342" + \ + "02655178EE7E7236E8BFCC1C66BDDA17" + \ + "F2F67F65ADBF55E70009FE84F0477B18" + \ + "45B7E5B48231FBD89436794CE39D3651" + \ + "1F9F86CCE08E95430F6977E57FEE45A0" + \ + "44B3D7AFD72694C1FAA6D07645080363" + \ + "D2AC6451C1AE37B621A1" + MAC = "EFFA1488A73FDBCE5B91BBF9B8D51775" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec8(): + KEY = "A418BA1658A6F0D90830C58679F80AC4" + Kx = "43033791EEA9FF04B189958D562C6A5C" + MSG = "06" + MAC = "FF9561CC6E45FFFD4388003AA5F61233" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec9(): + KEY = "651312D289F4DE957C208D35827C07E4" + Kx = "3854A163527454454441B1B4C7D3B835" + MSG = "D39E4B336C46FCDCFDF803A49EB3A603" + \ + "851CFCFA72B3A5F843768EBDEDEB9398" + \ + "91059275C79F1DADE2B97E288A91E3" + MAC = "9B1530F1AD35213EB8903D5610BFD7C4" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec10(): + KEY = "C960E0C80D89728D1FF952EFF5B83FEE" + Kx = "C0E47345C0AABE83D0BE0CE2624D9097" + MSG = "21" + MAC = "4EBEE65E5DD0C30F89C8ED49A3D2BF32" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec11(): + KEY = "313CE6FF4F18B9357C6EB292C55C0D22" + Kx = "4CDA79316AA8E3545DD4673189902BEC" + MSG = "7C74AF27F5A2CA6BC4207E4AA82FA3E2" + \ + "0D3A59D4E97CE43D62F2E2E1EFDD5AF4" + \ + "20AEB5C836D85975EECAB84D33481D2D" + \ + "694078D5C5A388FF9072C402C0E97CE6" + \ + "C6892AF97ADBAC35E0E4E61FC497091A" + \ + "D5B577AF64842F7D26B538C31357B504" + \ + "4ED187AA1D24B38E9343F5E0BC683BF8" + \ + "68A92D0B71CC81415AADD2C4A3E82189" + \ + "2FE1D1F2105FFDB101E91B21" + MAC = "74637ECB978422D4426F8F876A70E721" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec12(): + KEY = "8F4EC0BE7A3F5B6A2AAA92814F454F70" + Kx = "0EE5492230A06FA5A2F89D767923B58D" + MSG = "6CB1DB9648E809AC7B0988B160B20BED" + \ + "144A648DB75E854E50A2CA0F8D5F13FE" + \ + "70FF229CE427315651BD" + MAC = "CFF39D67CB2B1987DDE2841E4C7F6225" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec13(): + KEY = "AEA00AD0EF9243833DA4861D6A0D2C8C" + Kx = "50368F14FF9E0252897F46B2D4C92142" + MSG = "" + MAC = "954230A72692BAB4CE1A44473D081376" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec14(): + KEY = "F91F1CF58941608F6F08ED190D3BF9B0" + Kx = "125544328737911A0A9415C9CFA07712" + MSG = "CB09216F785295157058E08B38579E91" + \ + "AB808E8E02D47A508A78E1705D4847C6" + \ + "F3E52E15FA8611EECB7AFEAF0C8ED5E4" + \ + "5A1E38C4F02335F68ED1E4FF7024B728" + \ + "10199752298997246EA0C387D6CB43FC" + \ + "A3FD153E0F83D6CFB0378629A1127EA6" + \ + "C3D69EF3F683BAD18714565060AD20C3" + \ + "8DE75C720F79188D43C8A1F2026E825B" + \ + "211CC4FF2C50061F4343B7FB2C856E02" + \ + "16C29BB9B60B9749BD11AF2DE1C7CF19" + \ + "91FA2F43E820973DE13C2FCBC11D60BE" + \ + "599FDB3FD2C9A516857A411BA0D93E7B" + \ + "749E6A32552B19F52B5ED879DBCC88A0" + \ + "B0F1D342EC8F46C85418BE6EDF7C9C08" + \ + "FEB45623B22E682E85E61474F02C3AB8" + \ + "F2A16AAF05FC8FE5" + MAC = "5D5E7B4182EBD50B31FFE52DE4AB5C11" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec15(): + KEY = "57A2DD3D6DAB16AFC1D07B277664ED82" + Kx = "7F2FCD9F8E4A8E3725F0071B9C8743B4" + MSG = "D2D728DE057B3E" + MAC = "DBDEC069CF2B46450CEFB34FFD80D840" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec16(): + KEY = "11ED02022570CB10502BC1DACF64B21F" + Kx = "B6BB0A6CC3CA379226EFDB9D6C457EDC" + MSG = "E825603F896A85CAB45E6730D89DD4CE" + \ + "78010599" + MAC = "4A1577C366D53080D0DFD1CC47EE3CC7" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec17(): + KEY = "DD315EE3E236161FB777CAC2EC8A29C7" + Kx = "1AD7728D6A4A0520114B130B9D55BD81" + MSG = "469CCC" + MAC = "E45A7903A8B9B0366309BB11A451E244" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec18(): + KEY = "5AA9F6C6DE5138113DF5D6B6C77D5D52" + Kx = "2AE0EBD376BCD4A27B1CD406D2431CF9" + MSG = "A4434D740C2CB665FE5396959189383F" + MAC = "8B43ADF767E46B692E8F24E837CB5EFC" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec19(): + KEY = "4F41663FB985F7B47200246449B3DF33" + Kx = "80AEF0373782D05177726FFB0FA4F3C2" + MSG = "52D12581AC3FA13F2135F325130424AC" + MAC = "D21C5F1F7881C84540373E4AF9C01714" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec20(): + KEY = "FDDA1F4B99010C07521C4B74633559D3" + Kx = "FCB9B67395C53881D443449302C0D47D" + MSG = "BE" + MAC = "D3C4EE477F4FA5092B1FE726C18C3D01" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec21(): + KEY = "0D46557550CB313F36AFBA87625D961A" + Kx = "3273289C6F7DBD9140A3AC11AB96F495" + MSG = "90" + MAC = "F7C8553DED574829E6EE68112CB3817B" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec22(): + KEY = "F32DDBECDB1F527C06B46B3FCDD8F623" + Kx = "D2957F516B0DF1971B6B2147C68213B2" + MSG = "9CB9DCD3FB3DB886ACAB218F7D522899" + \ + "64EF11ECBAA8051B2290BD23EC9F8448" + \ + "1CAA5773FF18E0E299F55A094AB05086" + \ + "CD894D51C3252BF4B3C0" + MAC = "9E1107B058A7C310F41AFEDB3C0E58CA" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec23(): + KEY = "B06A7F949A0D26D872D2FAB4994B0E2F" + Kx = "3A805DB26699EBE2A3CA749A9888E06F" + MSG = "7240375662513285F67F63C03E677562" + MAC = "4249F423B3137D3C5EF9A315C4BFD1D3" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec24(): + KEY = "055A4CE2713D7D8B18EF014394D266A6" + Kx = "359AE1AA196387EC39F9E8E608FDC826" + MSG = "" + MAC = "8D8FDCF864C745DF8ABAAFADA00F5074" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec25(): + KEY = "2A473E38BBF4537C5397F45AE498CD4D" + Kx = "5D5F27EC92608C0712D3878A83F7B0E4" + MSG = "C2AC3D7250EEF02318BC084F294B1AC7" + \ + "2291EE1DC02AF424941CAAC685FCA59D" + \ + "9008679B00C56A0562583BDAEC0BBA" + MAC = "66DC2BCE269B793B4ACA1A4D04DDD668" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec26(): + KEY = "4DB286486F2B417498B819DD33442A9E" + Kx = "D41D109EA30E10E137CAE834B59F8B14" + MSG = "E37EC65C26E8BA67EF193889625C13FE" + \ + "B436724E93CFE3E7E836C138BA1EC381" + \ + "4C996A34C0EB4943860CA99EE154D1E7" + \ + "169F67E1F8708D149ADE74EF2782ADD0" + \ + "56B63CC8F2DF3EC8EC2EC78725450693" + \ + "65D9221BB7E188DC0C5599E177591C04" + \ + "5FD9472A1809F536609FF4CAA806EE55" + \ + "D8E08A4D5F911875" + MAC = "39D04705396D2ABD4CA96B693FC20B04" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec27(): + KEY = "2E5FBC9C465D509212C3274CFEDC7B5C" + Kx = "77A89510033CEBFFD5EB02AC2DC518B3" + MSG = "BE" + MAC = "BE0A9F7E4F4C9C55A35D0F90DC0FF866" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec28(): + KEY = "340567430897CFCEA4CEC0D2FBB84C58" + Kx = "2A22AC48EFA945339B22E335464B4B96" + MSG = "E5DEA257FC642D6A74D60187702BB635" + MAC = "B9A019E7BB4A84929365B6414D84B849" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec29(): + KEY = "0254B8C2431E598C2BE0C20F8AFBB8C7" + Kx = "E880EF06E1A19AF718B35E80D32E45AA" + MSG = "EC" + MAC = "CC6D34A67B2E3F08221F1F23C498F3B8" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec30(): + KEY = "0C32A26430F8BE4A8B8D9523EEAE969F" + Kx = "0A0D8002F377B0C00F7AF0F5A9E71753" + MSG = "1BA21EDF781D39FC69DC8F6F15488520" + \ + "DFEE60CDE1553579670D0A31EC9288A0" + \ + "AFC1F1908385B7DA854D21B106B3D866" + \ + "107E94D8254849C66CA4776B130810D7" + \ + "53EEC05456F59C5936864893338473B3" + \ + "34A3206DFDB07B66772A23DF0D4CC67C" + \ + "3D4A5D17F2840F1BE13AA19E00B693E8" + \ + "30C4376FE8A2D9A2735ADC2CD2BD4CE9" + \ + "C0CB56E8265BC0AF94058CC20E" + MAC = "0C4222286E02A484217881644CD11A7E" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec31(): + KEY = "DD65C1973AAE481556949A70BBA498A8" + Kx = "AD46B292A44636C9935DAC161263AB3C" + MSG = "DE3560AAC2D50387DBE216179395F41B" + MAC = "E19DA6375B7D44AC7EF2DC379E496775" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec32(): + KEY = "94970E03D46936BB786BB72807B1BB67" + Kx = "200B7BB09B59E00D4561DA915298BDA5" + MSG = "ED78D9458D" + MAC = "E9779A2E7A2F713C3692E71D1704AA00" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec33(): + KEY = "7BB18459270EA38C4EB115EAE374FEA4" + Kx = "10CD915058439C89AE22B6CB9712804B" + MSG = "2927AE423C96C4BAA61E34BE46EE8436" + MAC = "B342A9697FC469EC29D554E24742936E" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec34(): + KEY = "1E44A8857A620951EA738A31BBBB21BC" + Kx = "C4921E131FCC7E2B35A78860AF480902" + MSG = "17EA78DED1A793E12B9C86796D131274" + \ + "5605C71D5D58C90B92FEEBFC7855389C" + \ + "FA61075930A6A8BA7670BED604B84DA7" + \ + "0F4713088A6D78BE20" + MAC = "FF3D98D31F457AE0D957601ED44F3777" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec35(): + KEY = "6D4BD3BC9668D663E97F0C0CB844AF5C" + Kx = "E37C71B522A797C67EFC6F5B54683C10" + MSG = "06DAB144ED31412F118CE94838C25AD5" + \ + "FEE008E8721B" + MAC = "6BE23B4AFE1F608BCA215E94D7AADA51" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec36(): + KEY = "38419B570263AC7EC78B252E66712277" + Kx = "ADAB17D7BCCA53117BA64E2E553F88FE" + MSG = "F323C37F8255860DC6E4B07FEBA16FA9" + MAC = "C2D8DAC25EDC2FB9E9F2DCD010AFF945" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec37(): + KEY = "952FDE8393C45D230A5BE9B38636D154" + Kx = "6F97C6586DED928DEFFEFCBB7C71C643" + MSG = "D7800E257001A774AE7BCFB2CE1307B5" + \ + "B044" + MAC = "05F1CE30451A03A6E468B3A59033A554" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec38(): + KEY = "2EC5A074266CD3868F125C40A85C51D2" + Kx = "D5A7EBFC1FA31D74ADA27815426746F8" + MSG = "C3B6AE5BE019" + MAC = "003EB550D462D3E9A2ED9BD4B798C87F" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec39(): + KEY = "01B823CA9E8EFE175836625AA152E972" + Kx = "A38CD6F22953DB258CB5ABBB508EF884" + MSG = "61" + MAC = "32A2D28599066AA0DDCD1DFB6C3373B0" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec40(): + KEY = "FC5558E552206A0FF2194552D1CE6B48" + Kx = "7035246DCE824EE244DE68B5BA8C0324" + MSG = "9B5B542E0A39512195ED0EA6A0BCCE71" + MAC = "2797A78D54BE757328F7A00C4B522B2C" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec41(): + KEY = "B93BDEAD484349154F801B064C5BBB29" + Kx = "A53A9086733E606616E5AB6C956B07CC" + MSG = "B647" + MAC = "0C808D5AE0364B41B122EDB487397BB9" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec42(): + KEY = "E718EE5C2C37AC31129DD60377CB97AF" + Kx = "C1A134D29738702C49E2A03DF3C8E13E" + MSG = "1E4BD43A31" + MAC = "7D45F28E5FAA0C2FA7379A3BBA4B2A6E" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec43(): + KEY = "E477385CD36D02F3F6945AE61DDDA24F" + Kx = "78AC2C1CC2DE88761BDB54687FDE79B1" + MSG = "5D96B808E8C5D7BDC8CD1922FA5234F9" + \ + "B5C9690184D4035571F3613C3A15E25F" + \ + "E2ED87E17F53EAA82A352EC7" + MAC = "B7F4DB09E5C5A9133D60AAFC283D270D" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec44(): + KEY = "41C4238B6E55539E0B55C089936396F5" + Kx = "5E5CA473E94481320189974EC5108FDA" + MSG = "" + MAC = "AA7032ED436E7B52808E2E703F8781A1" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec45(): + KEY = "B2EABA3F0CCB537962DEC1D64EA63B13" + Kx = "17A233E56C5B8C1660D7849D41745971" + MSG = "C243538D2DFD4D1CBCF54490B27BDD87" + \ + "8416C01ADCF0C0" + MAC = "0BC42ECAC57934BC09899693664C2FF5" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec46(): + KEY = "4A7F71E3574FEA248ECC9EF0A667B2DF" + Kx = "5D3F47D30189B1EA1502BDA01D0B9D66" + MSG = "7D469C2A5E8C28BA15B308D183080DBB" + \ + "1AF6CDD2D1B6C3148B3620D236F2147F" + \ + "4BD7" + MAC = "82B9D1AF7643DE20A65117D1FBA48C7C" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec47(): + KEY = "CD38D5B8F8C3C26A7818951E225EA424" + Kx = "7E064526AF6D0804C37BB5D2B5D0DA35" + MSG = "C682889F28" + MAC = "093C98AFB1CA352477A296D97611BC72" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec48(): + KEY = "6C5683229E8985AC3BD5E661FD0A1066" + Kx = "A1878860BE9382E82E2B55FF12466D17" + MSG = "C1" + MAC = "9F65E3937D6C9140FF9B02857ADAFB5B" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec49(): + KEY = "2D113F05F079BF06B54D19D0566BE656" + Kx = "E54ABD326A766100B7F7F15407601DB8" + MSG = "CF" + MAC = "25938AC2F0F78B21416D5BA1D3642B63" + execute_test(KEY, Kx, MSG, MAC) + + +def test_vec50(): + KEY = "3E521285C1B089D7083214AA2871E299" + Kx = "C506FC8DC3D9E0179913B9866A3622AD" + MSG = "99472DB3A480E63173D39E9F5D" + MAC = "132A1027AD89A5F26C200966D581554B" + execute_test(KEY, Kx, MSG, MAC) + diff --git a/test_lrp_eval_vec.py b/test_lrp_eval_vec.py new file mode 100644 index 0000000..162df7f --- /dev/null +++ b/test_lrp_eval_vec.py @@ -0,0 +1,467 @@ +""" +Test vectors from AN12304 +""" + +import binascii + +from lrp import LRP + + +def execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES): + KEY = binascii.unhexlify(KEY) + RES = binascii.unhexlify(RES) + FINALIZE = FINALIZE == 1 + + assert LRP.eval_lrp(LRP.generate_plaintexts(KEY), LRP.generate_updated_keys(KEY)[UPDATEDKEY], IV, FINALIZE)\ + .hex().upper() == RES.hex().upper() + + +def test_vec1(): + KEY = "567826B8DA8E768432A9548DBE4AA3A0" + IV = "1359" + FINALIZE = 1 + UPDATEDKEY = 2 + RES = "1BA2C0C578996BC497DD181C6885A9DD" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec2(): + KEY = "B65557CE0E9B4C5886F232200113562B" + IV = "BB4FCF27C94076F756AB030D" + FINALIZE = 0 + UPDATEDKEY = 1 + RES = "6FDFA8D2A6AA8476BF94E71F25637F96" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec3(): + KEY = "88B95581002057A93E421EFE4076338B" + IV = "77299D" + FINALIZE = 1 + UPDATEDKEY = 2 + RES = "E9C04556A214AC3297B83E4BDF46F142" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec4(): + KEY = "C48A8E8B16571645A1557825AA66AC91" + IV = "1F0B7C0DB12889CA436CABB78BE42F9" + FINALIZE = 1 + UPDATEDKEY = 3 + RES = "51296B5E6D3B8DB8A1A7399760A19189" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec5(): + KEY = "CAF3750AFF93F9A0C8861BCCCCDF1A9D" + IV = "9273B7" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "468C2BFCF993E7F112E150C17298A968" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec6(): + KEY = "65024B14AA99E9CA93F51172E19EE000" + IV = "826CE8A26DFE768D91" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "A3830865D52EAEBC6471CDBD3DFC0A89" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec7(): + KEY = "1EDB9D253DF18D72BEEAE960B6FDF325" + IV = "FD7BBC6CE819F04AF0C3944C9E" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "B73B50D4BA439DF9D4AFB79FF10F1446" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec8(): + KEY = "08CFACB758EB34F0106D42358F22B5EB" + IV = "431B8F155EB1F28334F201CADD7" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "40C01FC5DF4C142D9C9721F74A373BA5" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec9(): + KEY = "CC57E7503BCCCF260D6B4E2AB38ACE94" + IV = "4D09838DF371FAC5D5B641EE45" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "C1A465936A097FF76FCAF18166E8DF60" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec10(): + KEY = "D0E9C3CACE9A747A74F582AA0F873FF9" + IV = "FCB69068C83E64765676F718E41E25" + FINALIZE = 1 + UPDATEDKEY = 2 + RES = "A944D5A19C5B86392CC3CFC58F57C321" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec11(): + KEY = "59C9C703C66A9FD2948E0A48617285DC" + IV = "F28EFF672184665744FD835B106484" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "F078390B345FC6E22EE9A75B3D8BF490" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec12(): + KEY = "2E763263979117BED33A331B15E3F01B" + IV = "2B96BFF1A8429C6E" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "9193DA3870AA345EB4FDFB5EE4A35E61" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec13(): + KEY = "A14E397DA6C410440FA9EC4C61774094" + IV = "4B42600D" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "21C0B442BF41B7DDD80D4A99CD7B7B81" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec14(): + KEY = "921038ED913CCEEFC6286B756F9ABC8D" + IV = "9FE171DCB4CA1F7E5" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "9FF1DBB5E8528E56370EB55919642AC0" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec15(): + KEY = "F2512BC694E7A66D6ED67E0841BA2523" + IV = "D0F92AC3F33EC12CF5B65C6ECE12DE0" + FINALIZE = 1 + UPDATEDKEY = 3 + RES = "6271F38386E7399D7FA1709A72B4F585" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec16(): + KEY = "75FCA5E188F44F1E808597A0B7B690D4" + IV = "64962F5DED0468F1" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "EBD6F32ED75566E6756A14EC16715CBD" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec17(): + KEY = "1000076C2934BDB02750204704DAA472" + IV = "8C3E0" + FINALIZE = 1 + UPDATEDKEY = 2 + RES = "581C3B057F9312FECF4A7B8070C83B8C" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec18(): + KEY = "99B1647A76CD170EA07997043E1E7919" + IV = "F" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "BA5F895E8B57F7753EE5C7276E60B37F" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec19(): + KEY = "6983FC665FBB8BEA35DADBB2EF446656" + IV = "BDF09818B0A7AFFF9C8" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "E0A4144033A1CACD1DBCE30F9883A1DB" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec20(): + KEY = "9FBC2045FA6215B4FD1ABA412DD9C59D" + IV = "F9B72310BDAE086C51D354B65F1F05F1" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "3F410411D5ED704572D06EDE6AB45CA2" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec21(): + KEY = "1EBB6DF4E251A10B9503AE6B3EEB0ACA" + IV = "CDD68EFF713C8" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "28740D45D92737D6CF8F05D05B961424" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec22(): + KEY = "415F46BA9A3C3C44A7E1782117668105" + IV = "590012E84AEC7" + FINALIZE = 0 + UPDATEDKEY = 2 + RES = "9852EFC35E53F2A4E8DA55770123C99D" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec23(): + KEY = "371A061E4A3065D00F41C4DA68722FFA" + IV = "52C78A675488D" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "FD2BDCC3EA26AF2069A4C536E3D6B33B" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec24(): + KEY = "E28DFE591559441D04213D889747BC46" + IV = "414E42E7" + FINALIZE = 1 + UPDATEDKEY = 2 + RES = "5E8BF483C2D6DA906EC58D1B63AC9887" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec25(): + KEY = "18A4209AAEF2CFC67E48834ED7D2B62B" + IV = "4B6E0EBCBB920A0B441114478" + FINALIZE = 0 + UPDATEDKEY = 0 + RES = "D054F91224DAC4C9E46EDF7EFAB6D179" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec26(): + KEY = "FBBCE5B5F4BF962A345BBF3F13F9E474" + IV = "D6B8F778C25" + FINALIZE = 1 + UPDATEDKEY = 2 + RES = "73C265CD18C9F909784DCFC4CAA5109D" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec27(): + KEY = "8E90A2AEBEB136C000521AEC0037ACFF" + IV = "B3FD7B7F1026CF70FF71CF8" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "7F519F9B9EAB01EF8DED79520C46770E" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec28(): + KEY = "FA89CC662EF47C75A9887F12A6C9879F" + IV = "B9" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "4973ECE66EEE903D4761EF3960210735" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec29(): + KEY = "3F0E5E6D0F7F7BDE4DB2C4F074D02062" + IV = "7D0AA4C30A75FC6C6A5D47D12247" + FINALIZE = 1 + UPDATEDKEY = 3 + RES = "87F43A64DAF93DF744F54FECE1A480AB" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec30(): + KEY = "B443EC2B5E56AF789D27F6C38F9DD6A9" + IV = "0CACAE327B04E870A3151E967" + FINALIZE = 0 + UPDATEDKEY = 0 + RES = "795553EBFA89AD541C0ED2E5F3C4611F" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec31(): + KEY = "7DD9BF8D3337D57ACD92069B13B16CCE" + IV = "2266169A6882C7E84" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "49F4FFFEA580EC96D5DCACC9E10AA95E" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec32(): + KEY = "B39A5A07AB6746B5DE4875ED9492DF1B" + IV = "F03704D4806A731" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "635E39AEF94D050B5424E1D967027594" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec33(): + KEY = "E2703DC54BF4E7C63337FFF0AB6BB6F0" + IV = "35D183BB4C56E8F70B" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "3E537D77DE31EA05C33CE70B4ECE65FA" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec34(): + KEY = "DF19EF9394EE6344A0832AF8ADCBABE4" + IV = "44CB4DE4352D3E45F5" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "80F1A5169142107FF0873BC4222E8173" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec35(): + KEY = "24E6DD53E9FEE719486C5CBD07714FC8" + IV = "24B80F682AF9B33" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "4FA0477728E34E1408D98643F8124035" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec36(): + KEY = "FAE4C2544FF93C20BAA6D60FAFE4919B" + IV = "87C4DB" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "FD2847D87ADC24C27FA042D1DCA1459B" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec37(): + KEY = "6D1902203D17BCBCE3A0A961EC358517" + IV = "CA5195213C2C75D37DCC6A67" + FINALIZE = 1 + UPDATEDKEY = 3 + RES = "2EADE5706A4BCD7CAF844DE01B127CE0" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec38(): + KEY = "7BC16676A8522EBC2564FEC235654DF8" + IV = "A885" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "9819FE9556933E1CFC4E99C8BF64ACFA" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec39(): + KEY = "F989FF4BDDD5AB6999EF517B742EA085" + IV = "C4DE07A5E" + FINALIZE = 0 + UPDATEDKEY = 0 + RES = "D6FEE60DBC8BA533E320ED1D18076D82" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec40(): + KEY = "5F07C727DA21B6C1E2688237672BCB7D" + IV = "8C74AC47C037AD729D38E3A" + FINALIZE = 0 + UPDATEDKEY = 0 + RES = "6021FC212F818102027C61FCE28D382C" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec41(): + KEY = "549C67ECD60E848F773990990CAC681E" + IV = "475BB41878EB17468F7A68847DDD3BAC" + FINALIZE = 1 + UPDATEDKEY = 3 + RES = "C3B5EE74A722E784887C4C9FDB497855" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec42(): + KEY = "9AFF3EF56FFEC3153B1CADB48B445409" + IV = "4B073B247CD48F7E0A" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "909415E5C8BE77563050F2227E17C0E4" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec43(): + KEY = "F2BBB25D607ECD1E551CD75CF0033CCE" + IV = "0335137B5641EFA4F176836A65F0F49" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "87832A9AF79C6CE436EA4DB6CAB18203" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec44(): + KEY = "806A50530D7735B40AC4EF1638E8AD6A" + IV = "D4137764716DBC8C579BEAB7E76754E" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "CF991392F0369350A7E21BE52F748821" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec45(): + KEY = "64193EF6BDDDC74C7C008DB98ED5FF67" + IV = "89AB" + FINALIZE = 1 + UPDATEDKEY = 3 + RES = "4A828E35DBADF6A465321363717D0D27" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec46(): + KEY = "F9E29780209AC952DD87C2572C4950BF" + IV = "35AF18F46C2FD3C8C6EB507147CA35A" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "51F3482AB8880850390F4F6D775F5C1F" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec47(): + KEY = "37A6769D43FEFA9F79CA61628BAFA7F1" + IV = "FB" + FINALIZE = 1 + UPDATEDKEY = 0 + RES = "81C84283D18071F08DE72AD51B5826B6" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec48(): + KEY = "047568AC57D4DE026C40F7228BDD1819" + IV = "F1B11" + FINALIZE = 0 + UPDATEDKEY = 3 + RES = "9CE6BEC0F80FDF7D78B1C219130102E7" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec49(): + KEY = "F36472663A3BA87F3E76399C66C23EC9" + IV = "1FF73338D23ED6AE968" + FINALIZE = 1 + UPDATEDKEY = 1 + RES = "36DA0902796F4682034DB07D0FF58E28" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + + +def test_vec50(): + KEY = "906249E5AF810339F199A25AEC0281E8" + IV = "56DA443282912622BB92338F8CA" + FINALIZE = 1 + UPDATEDKEY = 2 + RES = "317600A76B5A7984A681D1D8855F86FC" + execute_test(KEY, IV, FINALIZE, UPDATEDKEY, RES) + diff --git a/test_lrp_sdm.py b/test_lrp_sdm.py new file mode 100644 index 0000000..a7a9c30 --- /dev/null +++ b/test_lrp_sdm.py @@ -0,0 +1,110 @@ +""" +A short example how to decrypt and validate CMAC for a simple SDM in LRP mode on NTAG 424 DNA. +""" + +import io + +from lrp import LRP + +import binascii + + +def test_lrp_sdm(): + key = binascii.unhexlify("00000000000000000000000000000000") + + # suppose that our NDEF URI payload is: + # https://AAE1508939ECF6FF26BCE407959AB1A5EC022819A35CD293x5E3DB82C19E3865F + # (this is just an example) + # settings: LRP mode, encrypted PICCData mirroring with CMAC + # with SDM MAC input offset: 7, SDM MAC offset: 56, PICC Data offset: 7 + # the dynamic part is: + msg = "AAE1508939ECF6FF26BCE407959AB1A5EC022819A35CD293x5E3DB82C19E3865F" + + # break it into pieces + iv = msg[:16] + picc_data, cmac = msg[16:].split('x') + + # decrypt our message + lrp = LRP(key, 0, binascii.unhexlify(iv), pad=False) + decrypted_msg = lrp.decrypt(binascii.unhexlify(picc_data)) + assert decrypted_msg.hex() == "c7042e1d222a63806a000016e2ca89d1" + + # create session key + # SV = 00h || 01h || 00h || 80h [ || UID] [ || SDMReadCtr] [ || ZeroPadding] || 1Eh || E1h + svstream = io.BytesIO() + svstream.write(b"\x00\x01\x00\x80") + svstream.write(decrypted_msg[1:11]) # UID || SDMReadCtr + + while (svstream.getbuffer().nbytes + 2) % 16 != 0: + svstream.write(b"\x00") + + svstream.write(b"\x1E\xE1") + + assert svstream.getbuffer().nbytes % 16 == 0 + + # generate master key + lrp = LRP(key, 0) + master_key = lrp.cmac(svstream.getvalue()) + + assert master_key.hex() == "99c2fd9c885c2ca3c9089c20057310c0" + + # generate actual MAC_LRP + mac_obj = LRP(master_key, 0) + # everything in hex since PICCData till the MAC offset + msg_no_cmac = (msg.split('x')[0] + 'x').encode('ascii') + full_tag = mac_obj.cmac(msg_no_cmac) + short_tag = bytes(bytearray([full_tag[i] for i in range(16) if i % 2 == 1])).hex() + + assert short_tag == cmac.lower() + + +def test_lrp_sdm_with_enc_file(): + key = binascii.unhexlify("00000000000000000000000000000000") + + # suppose our NDEF URI payload is: + # https://any.domain/?m=65628ED36888CF9C84797E43ECACF114C6ED9A5E101EB592 + # x4ADE304B5AB9474CB40AFFCAB0607A85x87E287E8135BFC06 + + msg = "65628ED36888CF9C84797E43ECACF114C6ED9A5E101EB592x4ADE304B5AB9474CB40AFFCAB0607A85x87E287E8135BFC06" + + # break into pieces + iv = msg[:16] + picc_data, enc_file_data, cmac = msg[16:].split('x') + + # decrypt our message + lrp = LRP(key, 0, binascii.unhexlify(iv), pad=False) + decrypted_msg = lrp.decrypt(binascii.unhexlify(picc_data)) + assert decrypted_msg.hex() == "c7042e1d222a63807b00002993571635" + + # create session key + # SV = 00h || 01h || 00h || 80h [ || UID] [ || SDMReadCtr] [ || ZeroPadding] || 1Eh || E1h + svstream = io.BytesIO() + svstream.write(b"\x00\x01\x00\x80") + svstream.write(decrypted_msg[1:11]) # UID || SDMReadCtr + + while (svstream.getbuffer().nbytes + 2) % 16 != 0: + svstream.write(b"\x00") + + svstream.write(b"\x1E\xE1") + + assert svstream.getbuffer().nbytes % 16 == 0 + + # generate master key + lrp = LRP(key, 0) + master_key = lrp.cmac(svstream.getvalue()) + + assert master_key.hex() == "817133dd9fff11b94fc2fb107aa4d971" + + # generate actual MAC_LRP + mac_obj = LRP(master_key, 0) + # everything in hex since PICCData till the MAC offset + msg_no_cmac = "any.domain/?m=65628ED36888CF9C84797E43ECACF114C6ED9A5E101EB592" \ + "x4ADE304B5AB9474CB40AFFCAB0607A85x".encode('ascii') + full_tag = mac_obj.cmac(msg_no_cmac) + short_tag = bytes(bytearray([full_tag[i] for i in range(16) if i % 2 == 1])).hex() + + assert cmac == short_tag.upper() + + # IV = SDMReadCtr || 00 00 00 + enc_obj = LRP(master_key, 1, r=decrypted_msg[8:11] + b"\x00" * 3, pad=False) + assert enc_obj.decrypt(binascii.unhexlify(enc_file_data)).decode('ascii') == "0102030400000000"