首页
社区
课程
招聘
[原创]kctf2022 秋季赛 第十题 两袖清风 wp
发表于: 2022-12-10 19:44 15572

[原创]kctf2022 秋季赛 第十题 两袖清风 wp

2022-12-10 19:44
15572

看见了1300行的f5,忍不住想关掉ida。

但是面对困难不要怕,经过一小会分析,我们恢复了一点细节。



作者在程序中插入了很多的 antidebug 技巧。同时字符串一般都用维吉尼亚进行了加密。


完成程序初始化之后,我们可以看到程序开始了校验逻辑。


将第一步份校验逻辑用python写下,可以发现那个模数n可以在factordb上查询到一个小因子p。

乍一看像是 RSA ,实际上是一个离散对数问题,flag的第一部分是长度为85的十六进制数据。

$ base^{flagpartone} \mod n = C $

那么作者在这里隐藏了离散对数问题吗?根据我们对n的另一个因子q的分析,q-1不为一个光滑数,所以没有办法在多项式时间求解该离散对数问题,也就是说我们知道了C无法求得flagpartone。

继续往下分析。


作者将获得的 C 进行flag的第二部分,flag的85-88字节,必须为ABAB,ABBA的形式的,连接C作为魔改AES的密钥。密文为一段硬编码的 C2 。该AES使用CBC模式,iv是b'ABCDEF0123456789'。

之后解密的内容我们记为 Code1 。也就是“decrypted”。


程序将解密后内容存入一个可读可写可执行的内存区域,最后使用ZwQueueApcThread创建一个
异步程序调用,这里把它当成call就行了。值得注意的是,解密后的内容在拷贝的过程会出现\0截断问题。

仅仅魔改了密钥扩展,该AES为修改密钥扩展的14轮AES。与常见的AES-128不同,这个AES使用256bit(32字节)密钥,加密块却是128bit。在98k成员的有限的知识中应该不存在算法缺点。

如果我们假设这里能顺利运行,我们的问题就变成了需要猜测明文可执行指令,和密文,求出密钥。显然这个场景的是不可解问题。约等于AES的已知明文攻击。在没有实现缺陷的情况下,不可求出密钥。

所以,我们认为,以上两步中我们可以控制输入的flag的第一和第二部分控制AES解密结果,只要确保第一个字节为 0xc3 也就是 ret 指令就能让程序完美运行。平均256次穷举就能获得一个通过上述所有检查的输入。

该步骤最多可产生 16 ^ 85 / 256 种解。


然后程序使用UUID的方式编码shellcode。


经过分析,程序会根据输入的flag条件,在程序main函数中存在正确或者失败的字符串的内存中写入good或者bad。所以我们可以根据第三部分来控制main函数中的输出,我们想覆盖main函数中字符串的位置为220。根据分析我们需要控制 ‘kctf’ + 数据长度单字节 + 数据 为20字节。

并且满足以下约束条件。

A数组代表输入hex中的的高位组成的数组,B数组代表输入hex中的的低位组成的数组。

这里宽松的约束条件也能产生很多组解。

笔者这里给出九组解。


 
 
 
 
 
 
# flag = input('Please enter your key:')
# print('Start cheking your key ...')
 
if len(flag) < 89:
    print('no!')
    return
 
n = 0x4F62187B5F6590C6CFF0FBDBBEBDAF60AA861BD2F66F8F7FFD57A66AE50DB7D2FFFFFFFFFFFFFFFFFFFFF
# factored from factordb
p = 193
q = n // p
assert isPrime(q)
assert n == p * q
 
base = 0xB20446102D1C343D0575674CA28EBC0419BCFE4D75682C2AC81C9502454650BDDAEF6968AF269B54C182
_pow = int(flag[: 85], 16)
powered = hex(pow(base, _pow, n))[2: ]
if len(powered) % 2 == 1: powered = powered[: -1]
encrypted = bytes.fromhex(powered)
# flag = input('Please enter your key:')
# print('Start cheking your key ...')
 
if len(flag) < 89:
    print('no!')
    return
 
n = 0x4F62187B5F6590C6CFF0FBDBBEBDAF60AA861BD2F66F8F7FFD57A66AE50DB7D2FFFFFFFFFFFFFFFFFFFFF
# factored from factordb
p = 193
q = n // p
assert isPrime(q)
assert n == p * q
 
base = 0xB20446102D1C343D0575674CA28EBC0419BCFE4D75682C2AC81C9502454650BDDAEF6968AF269B54C182
_pow = int(flag[: 85], 16)
powered = hex(pow(base, _pow, n))[2: ]
if len(powered) % 2 == 1: powered = powered[: -1]
encrypted = bytes.fromhex(powered)
 
 
 
 
 
part2 = flag[85: 89]
codes = bytes.fromhex(vigenere(bytes.fromhex('064C1E530006484807565B1B4A5003064A455D040A40440758071C1C57005D1C195754094F4F0652071B4A02000C484B54510E411853515C404806595A4F44005106404A0259594B4A02570E4A1C54545D4D4F53530F41445754061B485553081B1E5154084B4E50560C481B07520C4D1E5D040D4F1F55035D1C4457565E4A1E50560D1C1C54035B1A1C5353084F1956595E1C1F57545D1D4E5C020E4E4E0600084A1E00575E4E4E5D500A1C1E54555D401E00560D1A4D0150094E490652591C4D5207064D4A0055594E4B54050D1E1855530A49195C580A4F4A51570B4E1C00540C4A185607084B1C50070C40485452074D1950040E4F1C05565A1B4C5300061E4E52580A4B4D5D525D1C1857595E411F5C5109191F5C510F4C4C5256091A4B56540B481B005808401B00530E191C00570C194C5C570B194A07590C4B4B5C54594B4D575907491952550B484807515C4A1853075A1945560259484F000406494F52515C1B4A070406401E00075D4E1B00585A414D555859194950575C1B4F55075A494454535B4B1851510E4C4951005C4D1802535C1C1F56045D484C0259081C4B02550A4B4B5607061A4F57570F194A52530F4D45025207401E0557084A4D5C535A4B1B50530C4E4F52510F1E4E55520C4A1C5C590E4F1F07580F1A4D0154064B4957520E4B49525307494E06535A1A1807515A404554025C411801520B1D4D50575C1E1850580F484D54520A1C1C54030B4A485253094F1E5C53074D1F5556084C1C53075D1B455C040C481E0607091B185456091E44540559411B53585B481E5D58594F1E53575D414C0052071C4C53070C48195204061C45550408191956530A4A4C54510B1C4F55020B4D1C02075D4F1C54070C4A1957570A404F5D500B4B4A07595A411F06500D1E4457540D4A4E050559194507500E414C00540A1E1F54545B1B4F06035B4F4C06035E4A4D06520F4C1F05595D194A55055E4C4450550C4B4A07030849495C025E4E4402055D1A4907565E4A4B51555B4D4C005559481F50510C4C4806525C411954505B1E1E0657074E4B06040E1B1F50005C1C4D025708191E5605074B4A0556081A4F56000C4A4857585B4D1B00520B1E4E02565B4F4457590B4F4E02590A1C4B5C535B4C1B54540A481E54530D411C5002091B1851595949485558061D4956525B1E4D0654091E4A5C505C48485D59061D4D05530F1D1E5C070A4A4850045B411F57510D40485705081E1E56055A4E4D5C52591B1850575E4E1F05590C4E4551555A4A1B5500071C4E0558064F4550575C4F1B52590B484A5102094B4B53040D1C4D5D030E484501030E1B4E5D515A4B1B0555084E4855555D4B4D02520C4F1C56020B1B4406555A1C4F5303591E4400505E1A1F5453071C4452030E1A1F06075B1D4C02505D1B4C5255061D4B54530B4C4B5659074F4D540309411F02520E4A195C515D4B1901570B491B07510F404C55550B414A5300074C1E53000C1B4555590A494E57560E4A4B52555D1A4E55535C414453025E494E57570A1A1906530D4E4C00035B4A4D570359414A07000D484500515D4B1952585E1B1F55515A1A4901510B1E4B01535C404F5C025A401B07040C1A1B0558594C1952580F484A5C520C49455D00064D1851035A1B4C56000A1E4C02000F4E1950560C401E5400084D4A05565D1A4F53515B491C07070D4E1E01035E4B44565706414F5C075C1A455000074A4954590F48480759061E185D03061A4F06030D4C1E01070F491E5C005E484C5C57064A4E01055B4E1F560406194D5D025E4F4C55055C404D05050B481C50575A4C4954565A481B56580E484B5751064A4C0659061D4A52040A414E05020B4A4F0503594F4554070A1C195D0309191B05500C1C4B55040A4A1F57540E1A4551580B4D18505206194F55000C4E4F5C510F1C4550555D4D4557035D1B4555050C4F4406020A1B495207591C4857040A401B5C54094F1C51530E4A4C53550E4948025409494F015408494E005609191B54500C4F4C00590F1D4A54555C41190650084E48550308401C57560F414B50555A4A4901075C1B4D53030B4B1B07530C1E4806550A1D450555064E185400071E4A53045D1C4952540D404957545A1A4E5100091B1C05035E1A4F5204071B1F57565A4E185350594C4907520F1D4F51520A4A4F0552094E1B5151094C4D5004094E49020207401E54045B1D1E00045B4B1B01500848445605064B4F5D05084B4905515A491B0704591B485705064C1E5D590E1C1952525C1C1B06500B1C440756061B1F05075B194B54500B1A1F5400071D490500064D1951035C4B4C54590B1E4A01005C414B055406411907055B4D480500081E4F565607404A0058074C4F53530B4F1F05565D414F5203074F48075307484B5100084C4955030C1E485D520E4A4F5253064E1E05005A4F4C53590E1A1851005A1C1F52050E484406505E1C1B07020E1A4507545E484551050E1B1B06025B4A445359061D4A05520A1A4E50580A4D4E515708194F005907494952070A1B195704594B1E5354094D4902545E4B4D05045E1D4B00570D4C4802575D4E4D005209194853040B194E50020C1B4A00025D494951560D404502070D1D1E02520B1B49055707414E5D515A404B07500E1B445258081D1F05055D1A1E07540B1D18565608194901050E411B56540B4B1F07555A4C4F55030D404C54510C1D4953000F1C4807520C491E53565E4A1851535E4A1F5C055C4D4552585B4C4C57000819495003591E4D5C050A1A1850000A494801530A1A4B06035E4A4D505906404D53030B1A4E00570C411F0754064A4A575207481853575A4E1F53050E191C570507494952500D41445C00594C4A54500D4C1802040F41495202081B4453070A4E4D06555E4A4E00570A4F4457005E1D1955580F4D4C55045A1A4806550E4B445D505C1B4802560F4A4850520B1A4B52570B4E4B51565A404455030D4A19575706491B515507481C0504074C4A02545B401E50530F1B4456520B411901070C1E1F5D50071D4B5259591B1802540C4F1C52585A19445151064A4E05535A481F06055C1A4C545807481B57055C411F06505B4D180253091E1C06560F1B1F5356591C4C05030F4D490205084B4A01500E194E5D54594F4507590A191C05030C404950550F4B4405590F1A4C5D000F1E4C00040C41485C075A484D0551091C4D06030C1E1F01045C1E4D53595D40185C040B4F1B54030F1E4850555D4F4C5656074F185D0407491957515A1D4806525E194505560F4F485C525E4A180750591D1905535C4B4E51025D1C4F5D07094A4B06580F481C0255064E1C00005B1C4956530F481B05540C40195D545940480703084E1F05540F481C00570C4E4F5400064D4454020F491E01550C4B4D0053094D4802075E1D4C5C02064B455C515C1E4C06570E4D1B53555A4F1857045E1D1E01550E40455C040B4D1851070F1C1C51555B1A1F5D000E1D4D01580E4D4D53050E1E485D050B1A1F54570F4B445D56591A1C5751064D495C570A4A4B54570F4C4C54530F491806550B4E1854030E4E1C5C020B4E4B5D000D4B1E54570D1B4452070B404806555C401E55055E1D4507530B1A1F0251084D4D5C585E4948005809494A54565E1A4E5D59074A195652594F4A07050E4D4B0552064B1E5356081B4C02555949195C57594B1807580D1C4A06025B1B4800530F4D445605074A4D5C07094F4856520B4B4F01565E414C51520A484D5C5108401C02585A4E1E0155591B1B55560B4019060206484950075D401C06040C1D4B0557591D1E00030A4B4557545B4E4956590A404850500E4A4C5D030C484507535C4E4451575E1E1F0500591D4E54505B4C4A0200064B4E0557074A195C550E1A1907505E1D1B52570E4C1856570A4F4E56520B4D4C54020C4B4805530A4C4B52025A1C4D5C545E411F53535A4D4A5D510B414C5756071C4501515E1A1C5D5306191F5755094F4A01025D4A1E57050A4E1F535609401B53030D1E1B51020B1C1851520D1E4F5358084F1957045B4E1E5C0208401C57565D4F485003594E1C515706191C0500084D4B0105081C195D035B1E4952035E1E1E00000B4B4456545A4F4A5104591E4801025C1A1E53070F404A0500091D4C01040A4F4E50535D494C53005C4E1B05525E481E02570E484D53575C1A485254081C485058061A1E0102074C1E025259484955040C1B4852550D404A01025D4B4E02500C1B1B54595E4F4854510D1C1E50030A4C48025206491F565008194F05055C4A4F06550A4D4A505506414C02035D414A00565A1E1C0607084C4C0505094F455003084C4457020C4E440200074D1C55040B4A4A5D535D4E4452540A4B1807070E491807500A481950510C404C50565C1B4901045C191852005C4B4A5105591A4E5C530C194F5D02094A4F565707484D075107191C53035B1C1C56565D1E4C52555E1C4B57525A1E4B55555C1B1B060008484A53535D4B4555055A411C5D59091A4E5559061D1957520B1B1E05560C4D1954550649455D520C4D485305081D4B53540E4F1850595E4B4900075E191B0707591C1852500B194B5C525C1D18010206401F5D540D4A1E5653094F1906055D4F4B00025A1A1E07045D4B4407035E4F445C570B1B4955040C491F5303591A4557055D4A1900040E4F1C5C595C1B180556591E195759074F4856045C4D4902510A4B4C54510F194E5D070E4A1C05585B4D1C50580E4D4C51550B1B1B5055594F4D06075E4B4E0752084F190507591D1F57555A411C05580E414C53520F4F4F07045A4E485C520F4F1E5C560F4F4B0607094E1854580C494401075C194F5D005B4C4E00595D4E4D07045A4C1C5C560A1B4D01580E491B5C580C494557035A1D440754594F4A5452084A440704071B4B5D03064A1950570F404556540A4F480158084C1F51525D4A4F5200'), "?x}da").decode())
encrypted = part2.encode() + encrypted # vigenere(encrypted, "Y?j0?")
decrypted = aes_decrypt_cbc(codes, encrypted, b'ABCDEF0123456789')
part2 = flag[85: 89]
codes = bytes.fromhex(vigenere(bytes.fromhex('064C1E530006484807565B1B4A5003064A455D040A40440758071C1C57005D1C195754094F4F0652071B4A02000C484B54510E411853515C404806595A4F44005106404A0259594B4A02570E4A1C54545D4D4F53530F41445754061B485553081B1E5154084B4E50560C481B07520C4D1E5D040D4F1F55035D1C4457565E4A1E50560D1C1C54035B1A1C5353084F1956595E1C1F57545D1D4E5C020E4E4E0600084A1E00575E4E4E5D500A1C1E54555D401E00560D1A4D0150094E490652591C4D5207064D4A0055594E4B54050D1E1855530A49195C580A4F4A51570B4E1C00540C4A185607084B1C50070C40485452074D1950040E4F1C05565A1B4C5300061E4E52580A4B4D5D525D1C1857595E411F5C5109191F5C510F4C4C5256091A4B56540B481B005808401B00530E191C00570C194C5C570B194A07590C4B4B5C54594B4D575907491952550B484807515C4A1853075A1945560259484F000406494F52515C1B4A070406401E00075D4E1B00585A414D555859194950575C1B4F55075A494454535B4B1851510E4C4951005C4D1802535C1C1F56045D484C0259081C4B02550A4B4B5607061A4F57570F194A52530F4D45025207401E0557084A4D5C535A4B1B50530C4E4F52510F1E4E55520C4A1C5C590E4F1F07580F1A4D0154064B4957520E4B49525307494E06535A1A1807515A404554025C411801520B1D4D50575C1E1850580F484D54520A1C1C54030B4A485253094F1E5C53074D1F5556084C1C53075D1B455C040C481E0607091B185456091E44540559411B53585B481E5D58594F1E53575D414C0052071C4C53070C48195204061C45550408191956530A4A4C54510B1C4F55020B4D1C02075D4F1C54070C4A1957570A404F5D500B4B4A07595A411F06500D1E4457540D4A4E050559194507500E414C00540A1E1F54545B1B4F06035B4F4C06035E4A4D06520F4C1F05595D194A55055E4C4450550C4B4A07030849495C025E4E4402055D1A4907565E4A4B51555B4D4C005559481F50510C4C4806525C411954505B1E1E0657074E4B06040E1B1F50005C1C4D025708191E5605074B4A0556081A4F56000C4A4857585B4D1B00520B1E4E02565B4F4457590B4F4E02590A1C4B5C535B4C1B54540A481E54530D411C5002091B1851595949485558061D4956525B1E4D0654091E4A5C505C48485D59061D4D05530F1D1E5C070A4A4850045B411F57510D40485705081E1E56055A4E4D5C52591B1850575E4E1F05590C4E4551555A4A1B5500071C4E0558064F4550575C4F1B52590B484A5102094B4B53040D1C4D5D030E484501030E1B4E5D515A4B1B0555084E4855555D4B4D02520C4F1C56020B1B4406555A1C4F5303591E4400505E1A1F5453071C4452030E1A1F06075B1D4C02505D1B4C5255061D4B54530B4C4B5659074F4D540309411F02520E4A195C515D4B1901570B491B07510F404C55550B414A5300074C1E53000C1B4555590A494E57560E4A4B52555D1A4E55535C414453025E494E57570A1A1906530D4E4C00035B4A4D570359414A07000D484500515D4B1952585E1B1F55515A1A4901510B1E4B01535C404F5C025A401B07040C1A1B0558594C1952580F484A5C520C49455D00064D1851035A1B4C56000A1E4C02000F4E1950560C401E5400084D4A05565D1A4F53515B491C07070D4E1E01035E4B44565706414F5C075C1A455000074A4954590F48480759061E185D03061A4F06030D4C1E01070F491E5C005E484C5C57064A4E01055B4E1F560406194D5D025E4F4C55055C404D05050B481C50575A4C4954565A481B56580E484B5751064A4C0659061D4A52040A414E05020B4A4F0503594F4554070A1C195D0309191B05500C1C4B55040A4A1F57540E1A4551580B4D18505206194F55000C4E4F5C510F1C4550555D4D4557035D1B4555050C4F4406020A1B495207591C4857040A401B5C54094F1C51530E4A4C53550E4948025409494F015408494E005609191B54500C4F4C00590F1D4A54555C41190650084E48550308401C57560F414B50555A4A4901075C1B4D53030B4B1B07530C1E4806550A1D450555064E185400071E4A53045D1C4952540D404957545A1A4E5100091B1C05035E1A4F5204071B1F57565A4E185350594C4907520F1D4F51520A4A4F0552094E1B5151094C4D5004094E49020207401E54045B1D1E00045B4B1B01500848445605064B4F5D05084B4905515A491B0704591B485705064C1E5D590E1C1952525C1C1B06500B1C440756061B1F05075B194B54500B1A1F5400071D490500064D1951035C4B4C54590B1E4A01005C414B055406411907055B4D480500081E4F565607404A0058074C4F53530B4F1F05565D414F5203074F48075307484B5100084C4955030C1E485D520E4A4F5253064E1E05005A4F4C53590E1A1851005A1C1F52050E484406505E1C1B07020E1A4507545E484551050E1B1B06025B4A445359061D4A05520A1A4E50580A4D4E515708194F005907494952070A1B195704594B1E5354094D4902545E4B4D05045E1D4B00570D4C4802575D4E4D005209194853040B194E50020C1B4A00025D494951560D404502070D1D1E02520B1B49055707414E5D515A404B07500E1B445258081D1F05055D1A1E07540B1D18565608194901050E411B56540B4B1F07555A4C4F55030D404C54510C1D4953000F1C4807520C491E53565E4A1851535E4A1F5C055C4D4552585B4C4C57000819495003591E4D5C050A1A1850000A494801530A1A4B06035E4A4D505906404D53030B1A4E00570C411F0754064A4A575207481853575A4E1F53050E191C570507494952500D41445C00594C4A54500D4C1802040F41495202081B4453070A4E4D06555E4A4E00570A4F4457005E1D1955580F4D4C55045A1A4806550E4B445D505C1B4802560F4A4850520B1A4B52570B4E4B51565A404455030D4A19575706491B515507481C0504074C4A02545B401E50530F1B4456520B411901070C1E1F5D50071D4B5259591B1802540C4F1C52585A19445151064A4E05535A481F06055C1A4C545807481B57055C411F06505B4D180253091E1C06560F1B1F5356591C4C05030F4D490205084B4A01500E194E5D54594F4507590A191C05030C404950550F4B4405590F1A4C5D000F1E4C00040C41485C075A484D0551091C4D06030C1E1F01045C1E4D53595D40185C040B4F1B54030F1E4850555D4F4C5656074F185D0407491957515A1D4806525E194505560F4F485C525E4A180750591D1905535C4B4E51025D1C4F5D07094A4B06580F481C0255064E1C00005B1C4956530F481B05540C40195D545940480703084E1F05540F481C00570C4E4F5400064D4454020F491E01550C4B4D0053094D4802075E1D4C5C02064B455C515C1E4C06570E4D1B53555A4F1857045E1D1E01550E40455C040B4D1851070F1C1C51555B1A1F5D000E1D4D01580E4D4D53050E1E485D050B1A1F54570F4B445D56591A1C5751064D495C570A4A4B54570F4C4C54530F491806550B4E1854030E4E1C5C020B4E4B5D000D4B1E54570D1B4452070B404806555C401E55055E1D4507530B1A1F0251084D4D5C585E4948005809494A54565E1A4E5D59074A195652594F4A07050E4D4B0552064B1E5356081B4C02555949195C57594B1807580D1C4A06025B1B4800530F4D445605074A4D5C07094F4856520B4B4F01565E414C51520A484D5C5108401C02585A4E1E0155591B1B55560B4019060206484950075D401C06040C1D4B0557591D1E00030A4B4557545B4E4956590A404850500E4A4C5D030C484507535C4E4451575E1E1F0500591D4E54505B4C4A0200064B4E0557074A195C550E1A1907505E1D1B52570E4C1856570A4F4E56520B4D4C54020C4B4805530A4C4B52025A1C4D5C545E411F53535A4D4A5D510B414C5756071C4501515E1A1C5D5306191F5755094F4A01025D4A1E57050A4E1F535609401B53030D1E1B51020B1C1851520D1E4F5358084F1957045B4E1E5C0208401C57565D4F485003594E1C515706191C0500084D4B0105081C195D035B1E4952035E1E1E00000B4B4456545A4F4A5104591E4801025C1A1E53070F404A0500091D4C01040A4F4E50535D494C53005C4E1B05525E481E02570E484D53575C1A485254081C485058061A1E0102074C1E025259484955040C1B4852550D404A01025D4B4E02500C1B1B54595E4F4854510D1C1E50030A4C48025206491F565008194F05055C4A4F06550A4D4A505506414C02035D414A00565A1E1C0607084C4C0505094F455003084C4457020C4E440200074D1C55040B4A4A5D535D4E4452540A4B1807070E491807500A481950510C404C50565C1B4901045C191852005C4B4A5105591A4E5C530C194F5D02094A4F565707484D075107191C53035B1C1C56565D1E4C52555E1C4B57525A1E4B55555C1B1B060008484A53535D4B4555055A411C5D59091A4E5559061D1957520B1B1E05560C4D1954550649455D520C4D485305081D4B53540E4F1850595E4B4900075E191B0707591C1852500B194B5C525C1D18010206401F5D540D4A1E5653094F1906055D4F4B00025A1A1E07045D4B4407035E4F445C570B1B4955040C491F5303591A4557055D4A1900040E4F1C5C595C1B180556591E195759074F4856045C4D4902510A4B4C54510F194E5D070E4A1C05585B4D1C50580E4D4C51550B1B1B5055594F4D06075E4B4E0752084F190507591D1F57555A411C05580E414C53520F4F4F07045A4E485C520F4F1E5C560F4F4B0607094E1854580C494401075C194F5D005B4C4E00595D4E4D07045A4C1C5C560A1B4D01580E491B5C580C494557035A1D440754594F4A5452084A440704071B4B5D03064A1950570F404556540A4F480158084C1F51525D4A4F5200'), "?x}da").decode())
encrypted = part2.encode() + encrypted # vigenere(encrypted, "Y?j0?")
decrypted = aes_decrypt_cbc(codes, encrypted, b'ABCDEF0123456789')
 
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
// AES
typedef struct {
    unsigned char rk[15 * 4 * 4]; // round key
    unsigned char iv[16];
} AES_CONTEXT;
 
const unsigned char Sbox[256] = {
//  0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f
    0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, // 0
    0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, // 1
    0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, // 2
    0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, // 3
    0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, // 4
    0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, // 5
    0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, // 6
    0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, // 7
    0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, // 8
    0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, // 9
    0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, // a
    0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, // b
    0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, // c
    0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, // d
    0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, // e
    0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16  // f
};
 
const unsigned char InvSbox[256] = {
//  0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f
    0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, // 0
    0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, // 1
    0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e, // 2
    0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, // 3
    0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, // 4
    0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, // 5
    0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, // 6
    0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, // 7
    0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, // 8
    0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, // 9
    0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, // a
    0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, // b
    0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, // c
    0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, // d
    0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, // e
    0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d  // f
};
 
void KeyExpansion(AES_CONTEXT *ctx, const unsigned char* key) {
    unsigned char t[4];
    unsigned char tmp;
 
    memcpy(ctx->rk, key, 32);
 
    for(int i = 8; i < 15 * 4; i++) {
        memcpy(t, ctx->rk + 4 * (i - 1), 4);
        if (i % 8) {
            if (i % 8 == 4) {
                t[0] = Sbox[t[0]];
                t[1] = Sbox[t[1]];
                t[2] = Sbox[t[2]];
                t[3] = Sbox[t[3]];
            }
        } else {
            tmp = Sbox[t[1]];
            t[1] = Sbox[t[2]];
            t[2] = Sbox[t[3]];
            t[3] = Sbox[t[0]];
            unsigned char rc = 1;
            for (int j = 0; j < i / 8 - 1; j++)
                rc = (0x1B * (rc >> 7)) ^ (2 * rc);
            t[0] = rc ^ tmp;
        }
        ctx->rk[i * 4] = ctx->rk[i * 4 - 32] ^ t[0];
        ctx->rk[i * 4 + 1] = ctx->rk[i * 4 - 31] ^ t[1];
        ctx->rk[i * 4 + 2] = ctx->rk[i * 4 - 30] ^ t[2];
        ctx->rk[i * 4 + 3] = ctx->rk[i * 4 - 29] ^ t[3];
    }
}
 
unsigned char FFmul(unsigned char a, unsigned char b) {
    unsigned char bw[4];
    unsigned char res = 0;
    int i;
    bw[0] = b;
    for(i = 1; i < 4; i++) {
        bw[i] = bw[i - 1] << 1;
        if(bw[i - 1] & 0x80) {
            bw[i] ^= 0x1b;
        }
    }
    for(i = 0; i < 4; i++) {
        if((a >> i) & 0x01) {
            res ^= bw[i];
        }
    }
    return res;
}
 
void SubBytes(AES_CONTEXT *ctx, unsigned char* state) {
    for (int i = 0; i < 16; i++)
        state[i] = Sbox[state[i]];
}
 
void ShiftRows(AES_CONTEXT *ctx, unsigned char* state) {
    unsigned char tmp[4];
 
    *(unsigned int*) tmp = *(unsigned int*) (state + 4);
    state[7] = tmp[0];
    state[4] = tmp[1];
    state[5] = tmp[2];
    state[6] = tmp[3];
 
    *(unsigned int*) tmp = *(unsigned int*) (state + 8);
    state[10] = tmp[0];
    state[11] = tmp[1];
    state[8] = tmp[2];
    state[9] = tmp[3];
 
    *(unsigned int*) tmp = *(unsigned int*) (state + 12);
    state[13] = tmp[0];
    state[14] = tmp[1];
    state[15] = tmp[2];
    state[12] = tmp[3];
}
 
void MixColumns(AES_CONTEXT *ctx, unsigned char* state) {
    unsigned char tmp[16];
    memset(tmp, 0., 16);
 
    for (int i = 0; i < 4; i++) {
        tmp[i] = FFmul(2, state[0 + i]) ^ FFmul(3, state[4 + i]) ^ FFmul(1, state[8 + i]) ^ FFmul(1, state[12 + i]);
        tmp[i + 4] = FFmul(1, state[0 + i]) ^ FFmul(2, state[4 + i]) ^ FFmul(3, state[8 + i]) ^ FFmul(1, state[12 + i]);
        tmp[i + 8] = FFmul(1, state[0 + i]) ^ FFmul(1, state[4 + i]) ^ FFmul(2, state[8 + i]) ^ FFmul(3, state[12 + i]);
        tmp[i + 12] = FFmul(3, state[0 + i]) ^ FFmul(1, state[4 + i]) ^ FFmul(1, state[8 + i]) ^ FFmul(2, state[12 + i]);
    }
    memcpy(state, tmp, 16);
}
 
void AddRoundKey(AES_CONTEXT *ctx, unsigned char* state, unsigned char* k) {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            state[i * 4 + j] ^= k[j * 4 + i];
        }
    }
}
 
void InvSubBytes(AES_CONTEXT *ctx, unsigned char* state) {
    for (int i = 0; i < 16; i++)
        state[i] = InvSbox[state[i]];
}
 
void InvShiftRows(AES_CONTEXT *ctx, unsigned char* state) {
    unsigned char tmp[4];
 
    tmp[0] = state[7];
    tmp[1] = state[4];
    tmp[2] = state[5];
    tmp[3] = state[6];
    *(unsigned int*) (state + 4) = *(unsigned int*) tmp;
 
    tmp[0] = state[10];
    tmp[1] = state[11];
    tmp[2] = state[8];
    tmp[3] = state[9];
    *(unsigned int*) (state + 8) = *(unsigned int*) tmp;
 
    tmp[0] = state[13];
    tmp[1] = state[14];
    tmp[2] = state[15];
    tmp[3] = state[12];
    *(unsigned int*) (state + 12) = *(unsigned int*) tmp;
}
 
void InvMixColumns(AES_CONTEXT *ctx, unsigned char* state) {
    unsigned char tmp[16];
    memset(tmp, 0., 16);
 
    for (int i = 0; i < 4; i++) {
        tmp[i] = FFmul(0x0e, state[0 + i]) ^ FFmul(0x0b, state[4 + i]) ^ FFmul(0x0d, state[8 + i]) ^ FFmul(0x09, state[12 + i]);
        tmp[i + 4] = FFmul(0x09, state[0 + i]) ^ FFmul(0x0e, state[4 + i]) ^ FFmul(0x0b, state[8 + i]) ^ FFmul(0x0d, state[12 + i]);
        tmp[i + 8] = FFmul(0x0d, state[0 + i]) ^ FFmul(0x09, state[4 + i]) ^ FFmul(0x0e, state[8 + i]) ^ FFmul(0x0b, state[12 + i]);
        tmp[i + 12] = FFmul(0x0b, state[0 + i]) ^ FFmul(0x0d, state[4 + i]) ^ FFmul(0x09, state[8 + i]) ^ FFmul(0x0e, state[12 + i]);
    }
    memcpy(state, tmp, 16);
}
 
void aes_init(AES_CONTEXT *ctx, const unsigned char* key, const void* iv) {
    // memcpy(ctx->Sbox, sBox, 256);
    // memcpy(ctx->InvSbox, invsBox, 256);
    KeyExpansion(ctx, key);
    if (iv) memcpy(ctx->iv, iv, 16);
}
 
unsigned char* aes_decrypt_block(AES_CONTEXT *ctx, unsigned char* input) {
    unsigned char state[16];
    int i, r, c;
 
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            state[i * 4 + j] = input[j * 4 + i];
        }
    }
 
    AddRoundKey(ctx, state, ctx->rk + 14 * 16);
 
    for (int i = 13; i > 0; i--) {
        InvSubBytes(ctx, state);
        InvShiftRows(ctx, state);
        AddRoundKey(ctx, state, ctx->rk + 16 * i);
        InvMixColumns(ctx, state);
    }
 
    InvSubBytes(ctx, state);
    InvShiftRows(ctx, state);
    AddRoundKey(ctx, state, ctx->rk);
 
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            input[i * 4 + j] = state[j * 4 + i];
        }
    }
 
    return input;
}
 
 
void aes_decrypt_ecb(const void* key, void* data, int data_len) {
    assert(data_len % 16 == 0);
    AES_CONTEXT ctx;
    aes_init(&ctx, (const unsigned char*) key, NULL);
    unsigned char* _data = (unsigned char*) data;
    for (int i = 0; i < data_len / 16; i++) {
        aes_decrypt_block(&ctx, _data);
        _data += 16;
    }
}
 
void aes_decrypt_cbc(const void* key, const void* iv, void* data, int data_len) {
    assert(data_len % 16 == 0);
    AES_CONTEXT ctx;
    aes_init(&ctx, (const unsigned char*) key, iv);
    unsigned char* _data = (unsigned char*) data;
    unsigned char buf[16];
    for (int i = 0; i < data_len / 16; i++) {
        memcpy(buf, _data, 16);
        aes_decrypt_block(&ctx, _data);
        for (int j = 0; j < 16; j++) _data[j] ^= ctx.iv[j];
        _data += 16;
        memcpy(ctx.iv, buf, 16);
    }
}
 
int main() {
    unsigned char data[] =
        "\x94\xC7\xA9\x05\xC7\xDC\x74\xB9\x28\x9E\x58\x9C\x98\xDA\x3A\xBD"
        "\xD3\x56\x72\xB3\x8C\x7F\xA3\x06\x00\x19\xE7\x0C\x85\xB8\xE7\x9D"
        "\x09\x87\xF8\xF3\x7F\x61\x2A\x05\xB5\x27\x20\x99\x35\x9C\x51\x27"
        "\xCC\x55\x73\x34\x73\x0F\xC3\x35\xC9\xE2\x7B\x1B\xBD\x93\x7A\x2C"
        "\x47\x2D\xA0\xBD\xBA\x72\x77\xD2\x8A\xDB\x35\xBE\x38\xC1\x63\xBA"
        "\x72\xCD\x6A\x63\x91\x5D\xC0\x4B\x8C\xD7\x2B\x0E\x16\x64\xB3\xFD";
 
    unsigned char key[] =  "\x44\x44\x45\x45\xaf\x20\x5d\xb8\xe5\x0e\xb8\x95\x2b\x78\x22\xcc\x7a\x3a\xeb\x55\x0c\x0a\xc9\xb7\xfc\xf1\x59\xc0\xe8\xc7\x29\xf4";
    unsigned char iv[] = "ABCDEF0123456789";
 
    #define BLOCK_SIZE 4
    unsigned char tmp[16 * BLOCK_SIZE];
 
    for (int i = 0; i < 100; i++) {
        memcpy(tmp, data, 16 * BLOCK_SIZE);
        key[0] = 0x30 + i / 10;
        key[1] = 0x30 + i / 10;
        key[2] = 0x30 + i % 10;
        key[3] = 0x30 + i % 10;
 
        aes_decrypt_cbc(key, iv, tmp, 16 * BLOCK_SIZE);
        if (tmp[0] == 0xC3) break;
    }
 
    printf("%s\n", tmp[0] == 0xc3 ? "Yes." : "No.");
 
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 16; j++) {
            printf("%02x ", key[i * 16 + j]);
        }
        putchar('\n');
    }
    putchar('\n');
 
    for (int i = 0; i < BLOCK_SIZE; i++) {
        for (int j = 0; j < 16; j++) {
            printf("%02x ", tmp[i * 16 + j]);
        }
        putchar('\n');
    }
 
    return 0;
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
// AES
typedef struct {
    unsigned char rk[15 * 4 * 4]; // round key
    unsigned char iv[16];
} AES_CONTEXT;
 
const unsigned char Sbox[256] = {
//  0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f
    0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, // 0
    0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, // 1
    0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, // 2
    0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, // 3
    0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, // 4
    0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, // 5
    0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, // 6
    0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, // 7
    0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, // 8
    0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, // 9
    0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, // a
    0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, // b
    0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, // c
    0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, // d
    0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, // e
    0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16  // f
};
 
const unsigned char InvSbox[256] = {
//  0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f
    0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, // 0
    0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, // 1
    0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e, // 2
    0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, // 3
    0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, // 4
    0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, // 5
    0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, // 6
    0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, // 7
    0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, // 8
    0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, // 9
    0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, // a
    0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, // b
    0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, // c
    0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, // d
    0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, // e
    0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d  // f
};
 
void KeyExpansion(AES_CONTEXT *ctx, const unsigned char* key) {
    unsigned char t[4];
    unsigned char tmp;
 
    memcpy(ctx->rk, key, 32);
 
    for(int i = 8; i < 15 * 4; i++) {
        memcpy(t, ctx->rk + 4 * (i - 1), 4);
        if (i % 8) {
            if (i % 8 == 4) {
                t[0] = Sbox[t[0]];
                t[1] = Sbox[t[1]];
                t[2] = Sbox[t[2]];
                t[3] = Sbox[t[3]];
            }
        } else {
            tmp = Sbox[t[1]];
            t[1] = Sbox[t[2]];
            t[2] = Sbox[t[3]];
            t[3] = Sbox[t[0]];
            unsigned char rc = 1;
            for (int j = 0; j < i / 8 - 1; j++)
                rc = (0x1B * (rc >> 7)) ^ (2 * rc);
            t[0] = rc ^ tmp;
        }
        ctx->rk[i * 4] = ctx->rk[i * 4 - 32] ^ t[0];
        ctx->rk[i * 4 + 1] = ctx->rk[i * 4 - 31] ^ t[1];
        ctx->rk[i * 4 + 2] = ctx->rk[i * 4 - 30] ^ t[2];
        ctx->rk[i * 4 + 3] = ctx->rk[i * 4 - 29] ^ t[3];
    }
}
 
unsigned char FFmul(unsigned char a, unsigned char b) {
    unsigned char bw[4];
    unsigned char res = 0;
    int i;
    bw[0] = b;
    for(i = 1; i < 4; i++) {
        bw[i] = bw[i - 1] << 1;
        if(bw[i - 1] & 0x80) {
            bw[i] ^= 0x1b;
        }
    }
    for(i = 0; i < 4; i++) {
        if((a >> i) & 0x01) {
            res ^= bw[i];
        }
    }
    return res;
}
 
void SubBytes(AES_CONTEXT *ctx, unsigned char* state) {
    for (int i = 0; i < 16; i++)
        state[i] = Sbox[state[i]];
}
 
void ShiftRows(AES_CONTEXT *ctx, unsigned char* state) {
    unsigned char tmp[4];
 
    *(unsigned int*) tmp = *(unsigned int*) (state + 4);
    state[7] = tmp[0];
    state[4] = tmp[1];
    state[5] = tmp[2];
    state[6] = tmp[3];
 
    *(unsigned int*) tmp = *(unsigned int*) (state + 8);
    state[10] = tmp[0];
    state[11] = tmp[1];
    state[8] = tmp[2];
    state[9] = tmp[3];
 
    *(unsigned int*) tmp = *(unsigned int*) (state + 12);
    state[13] = tmp[0];
    state[14] = tmp[1];
    state[15] = tmp[2];
    state[12] = tmp[3];
}
 
void MixColumns(AES_CONTEXT *ctx, unsigned char* state) {
    unsigned char tmp[16];
    memset(tmp, 0., 16);
 
    for (int i = 0; i < 4; i++) {

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-12-11 10:40 被全盲法师编辑 ,原因: 修改错别字
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//