• Nenhum resultado encontrado

Análise do ataque quadrado ao AES

N/A
N/A
Protected

Academic year: 2021

Share "Análise do ataque quadrado ao AES"

Copied!
104
0
0

Texto

(1)

CATARINA

CURSO DE GRADUA ¸

C ˜

AO EM CIˆ

ENCIAS DA

COMPUTA ¸

C ˜

AO

Paulo Soto de Miranda

An´

alise do ataque quadrado ao AES

Trabalho de Conclus˜

ao de Curso

Daniel Santana Freitas

(2)

ii

(3)
(4)

Agradecimentos

Agrade¸co principalmente os meus pais que tornaram poss´ıvel a mi-nha entrada na faculdade e que sempre me apoiaram quando precisava.

Ao professor Daniel Santana por me orientar nesse trabalho e tirar minhas d´uvidas com muita aten¸c˜ao.

Aos membros do Labsec que me ajudaram em quest˜oes t´ecnicas e que sempre foram ´otimos companheiros de trabalho.

(5)

Resumo

Este trabalho ´e uma an´alise te´orica e computacional de diferentes ataques quadrados aplicados ao algoritmo criptogr´afico AES.

A an´alise te´orica aborda os fundamentos matem´aticos usados no AES e nos ataques, a descri¸c˜ao detalhada do projeto do AES e a descri¸c˜ao de trˆes tipos de ataques quadrados: o ataque de primeira ordem sobre 4 e 6 rodadas e o ataque de quarta ordem sobre 5 rodadas do AES.

A an´alise computacional consiste na implementa¸c˜ao do AES e dos trˆes tipos de ataques na linguagem de programa¸c˜ao C++. Esses ataques foram elaborados por criptoanalistas e apresentados em congressos cient´ıficos, mas suas demostra¸c˜oes se restringiram apenas `a teoria. O m´erito desse trabalho ´e demostrar computacionalmente o funcionamento desses ataques.

(6)

Sum´

ario

Resumo 1 Sum´ario 2 Lista de Figuras 4 Lista de Tabelas 5 Lista de Siglas 6 1 Introdu¸c˜ao 7

2 Fundamentos Matem´aticos 10

2.1 Aritm´etica Modular . . . 10

2.2 Aritm´etica em Corpos de Galois . . . 11

2.3 Aritm´etica Polinomial . . . 13 3 O AES 16 3.1 ByteSub . . . 17 3.2 ShiftRow . . . 20 3.3 MixColumn . . . 20 3.4 AddRoundKey . . . 21 3.5 Deriva¸c˜ao de chave . . . 22 4 O Ataque Quadrado 26 4.1 Ataque de primeira ordem sobre 4 rodadas . . . 27

4.1.1 1a Rodada . . . 28

(7)

4.1.3 3a Rodada . . . 30

4.1.4 4a Rodada . . . 32

4.2 Ataque de primeira ordem sobre 6 rodadas . . . 35

4.2.1 Extens˜ao no final . . . 35

4.2.2 Extens˜ao no in´ıcio . . . 37

4.3 Ataque de quarta ordem sobre 5 rodadas . . . 39

5 Considera¸c˜oes Finais e Trabalhos Futuros 40 Referˆencias Bibliogr´aficas 41 Apˆendice 42 A C´odigo Fonte 42 B Artigo 88 Abstract 1 B.1 Introdu¸c˜ao . . . 1 B.2 O Ataque Quadrado . . . 1

B.2.1 Ataque de primeira ordem sobre 4 rodadas . . . 2

B.2.2 Ataque de primeira ordem sobre 6 rodadas . . . 6

B.2.3 Ataque de quarta ordem sobre 5 rodadas . . . 8

(8)
(9)

Lista de Tabelas

(10)

Lista de Siglas

AES - Advanced Encryption Standard DES - Data Encryption Standard C/C++ - Linguagem de Programa¸c˜ao NIST - National Institute of Standards RAM - Random Access Memory GF - Galois Field

ByteSub - substitui¸c˜ao byte a byte atrav´es de consultas a uma tabela InvByteSub - trasforma¸c˜ao inversa a ByteSub

ShiftRow - permuta¸c˜ao simples atrav´es de deslocamento de linhas InvShiftRow - trasforma¸c˜ao inversa a ShiftRow

MixColumn - substitui¸c˜ao atrav´es de opera¸c˜oes sobre uma coluna InvMixColumn - trasforma¸c˜ao inversa a MixColumn

AddRoundKey - aplica¸c˜ao de ou-exclusivo entre o bloco e a chave. BS - ByteSub

SR - ShiftRow MC - MixColumn KA - AddRoundKey

(11)

Cap´ıtulo 1

Introdu¸c˜

ao

A tecnologia da informa¸c˜ao tem evolu´ıdo muito e englobado v´arias ´areas da sociedade. Algumas dessas ´areas lidam com informa¸c˜oes muito importantes e sigilosas, como transa¸c˜oes banc´arias e estrat´egias governamentais. Logo, o dom´ınio da seguran¸ca de dados se tornou essencial.

A seguran¸ca de dados ´e composta por diversos servi¸cos que prov´em `as informa¸c˜oes do usu´ario:

• Confidencialidade: prote¸c˜ao contra leitura n˜ao autorizada;

• N˜ao-rep´udio: preven¸c˜ao de rep´udio por parte da origem da informa¸c˜ao. Por

exemplo, previni um emissor de uma mensagem negar a sua autoria;

• Autentica¸c˜ao: garantia que a comunica¸c˜ao ´e autentica. Provar que os

comu-nicantes s˜ao realmente quem eles dizem ser;

• Integridade: garantia que a informa¸c˜ao n˜ao foi alterada.

A base para esses servi¸cos de seguran¸ca ´e a criptografia. Ela ´e um processo usado para transformar um conjunto de dados leg´ıveis quaisquer em um conjunto de dados inintelig´ıvel. Essa opera¸c˜ao ´e chamada de cifragem e a sua inversa de decifragem.

(12)

8 A criptografia sim´etrica ´e mais r´apida e ´e usada para cifrar grandes quantidades de dados, como arquivos e comunica¸c˜ao entre computadores. A assi-m´etrica ´e mais lenta e ´e mais usada para cifrar pequena quantidade de dados, como resumo (”hash”) de arquivos, que s˜ao usados na assinatura digital.

A criptografia foi inventada na antig¨uidade e vem sendo usada e aprimorada at´e hoje. O principal uso da criptografia sempre foi as guerras. Os paises cifravam os dados para que os inimigos n˜ao os pudesse ler e ent˜ao descobrir os segredos b´elicos. Logo, sempre foi de grande interesse estudar estes mecanismos, tanto para construir algoritmos bons para se defender dos inimigos quanto para conseguir decifrar os dados do inimigo. A ciˆencia que faz an´alise desses algoritmos ´e chamada de criptoan´alise. O processo de inventar novos algoritmos e descobrir suas falhas acontece at´e hoje.

O algoritmo sim´etrico mais usado hoje em dia ´e o DES, Data En-cription Standard. A maioria dos sistemas de seguran¸ca tˆem ele como principal algoritmo. Ele foi estudado por v´arios anos por cientistas e foram descobertas v´a-rias falhas. Diante disso, foi necess´ario inventar outro algoritmo, que fosse mais seguro. Para isso, o NIST, National Institute of Standards and Tecnology, a agˆencia respons´avel pela padroniza¸c˜ao de tecnologias da ind´ustria americana, no ano 2000, fez um concurso para eleger um algoritmo para substituir o DES. As principais caracter´ısticas dos candidatos analisadas foram:

• Seguran¸ca geral: resistente contra os ataques j´a conhecidos;

• Custo: o algoritmo dever´a estar dispon´ıvel mundialmente e livre de taxas; • Computacionalmente eficiente: o algoritmo dever´a ser r´apido tanto em

imple-menta¸c˜oes em software e hardware;

• Pouco uso de mem´oria: o algoritmo dever´a usar pouca mem´oria, pois ele

poder´a ser implementado em hardware com pouca mem´oria RAM dispon´ıvel, como os smart cards;

• Flexibilidade: disponibilidade de diferentes tamanhos de bloco e chave e

(13)

• Simplicidade: o projeto do algoritmo deve ser simples, o que facilita a sua

implementa¸c˜ao e an´alise.

V´arios algoritmos foram submetidos ao processo de sele¸c˜ao. Os que chegaram `a fase final foram:

1. MARS; 2. RC6; 3. Rijndael; 4. Serpent; 5. Twofish.

O algoritmo chamado Rijndael foi escolhido para se tornar o novo algoritmo padr˜ao, que foi batizado de AES, Advanced Encryption Standard. Ele foi criado por dois criptoanalistas belgas chamados Joan Daemen and Vincent Rij-men. Diferente dos algoritmos utilizados anteriormente, o Rijndael tem como base a matem´atica. Ela provˆe um maior formalismo ao algoritmo, permitindo provar matematicamente a efic´acia dos mecanismos utilizados. Outra vantagem ´e que, por essas t´ecnicas j´a terem sido profundamente estudadas, n˜ao ´e necess´ario criar toda uma nova gama de t´ecnicas de an´alise espec´ıficas para ele, ´e poss´ıvel utilizar o em-basamento te´orico relativo `a matem´atica utilizada.

Com o novo algoritmo definido, a pesquisa de criptografia sim´etrica est´a concentrada em analis´a-lo. Alguns ataques j´a foram descobertos e dentre eles o mais eficaz ´e ataque quadrado.

Esse trabalho de conclus˜ao de curso tem como objetivo analisar as diferentes vers˜oes do ataque quadrado ao AES. Essa an´alise ´e composta pelo entendimento do ataque, a implementa¸c˜ao computacional e observa¸c˜oes sobre os resultados.

(14)

Cap´ıtulo 2

Fundamentos Matem´

aticos

O algoritmo criptogr´afico AES ´e um conjunto de passos que faz opera¸c˜oes sobre um bloco de dados. Cada bloco nada mais ´e do que um conjunto de n´umeros. Para o projeto do Rijndael, foram empregadas teorias matem´aticas relacionadas com conjuntos e opera¸c˜oes sobre n´umeros, que s˜ao: aritm´etica em corpos de Galois, aritm´etica polinomial e aritm´etica modular. Elas ser˜ao explicadas nas sess˜oes seguintes, de acordo com [2].

2.1

Aritm´

etica Modular

Dado dois inteiros a e b, se n´os dividirmos a por b, teremos o quo-ciente inteiro q e um resto inteiro r, que obedecem `a seguinte rela¸c˜ao:

a = qn + r 0 ≤ r < n; q = ba/nc O resto r ´e tamb´em conhecido como res´ıduo.

Se a ´e um inteiro e n ´e um inteiro positivo, definimos a mod b como o resto de a dividido por b.

Dois inteiros a e b s˜ao ditos ser congruentes m´odulo n, se (a mod n) = (b mod n). Sua nota¸c˜ao ´e a ≡ b mod n.

Definimos Zn como o conjunto de inteiros n˜ao negativos menores

que n:

(15)

Esse conjunto ´e referenciado como o conjunto de res´ıduos, ou classes de res´ıduos m´odulo n. Mais precisamente, cada inteiro de Zn representa uma classe

de res´ıduos. Todos n´umeros congruentes entre si m´odulo n pertencem a mesma classe de res´ıduos.

Se for efetuado aritm´etica modular em Zn, as seguintes

proprieda-des ser˜ao seguidas para os inteiros de Zn:

Propriedade Express˜ao

Comutatividade (w + x)mod n = (x + w)mod n (w × x)mod n = (x × w)mod n Associatividade [(w + x) + y]mod n = [w + (x + y)]mod n

[(w × x) × y]mod n = [w × (x × y)]mod n Distributividade [w × (x + y)]mod n = [(w × x) + w × y]mod n

[w + (x × y)]mod n = [(w + x) + w + y]mod n

Identidades (0 + w)mod n = w mod n

(1 × w)mod n = w mod n

Inversa aditiva P ara cada w ∈ Zn, existe um z tal que w + z ≡ 0 mod n

Tabela 2.1: Propriedades da Aritm´etica Modular

A existˆencia de uma inversa multiplicativa depende da condi¸c˜ao de que o n´umero a ser invertido deve ser relativamente primo ao n´umero com o qual est´a calculando o m´odulo, isto ´e, dado um n´umero a e deseja-se calcular seu inverso m´odulo um n´umero n, a−1s´o existir´a se a for relativamente primo a n. Dois n´umeros

s˜ao relativamente primos se eles s´o tiveram o n´umero 1 como divisor comum.

2.2

Aritm´

etica em Corpos de Galois

Na ´algebra abstrata, as opera¸c˜oes s˜ao feitas entre elementos que pertencem a um mesmo conjunto. O resultado dessas opera¸c˜oes dever´a pertencer ao mesmo conjunto dos operadores. Quais opera¸c˜oes satisfazem essa regra dentro de um conjunto vai depender das propriedades do conjunto. Sendo S um conjunto e • uma opera¸c˜ao qualquer definida para esse conjunto, as suas poss´ıveis propriedades s˜ao:

(16)

12 3. Elemento Identidade: existe um elemento e pertencente a S, tal que a•e = e•a

para todo a pertencente a S ;

4. Elemento Inverso: para cada a pertencente a S, existe um elemento a0 tamb´em pertencente a S, tal que a • a0 = a0 • a = e;

5. Comutatividade: a • b = b • a para todo a e b pertencentes a S.

Quando duas opera¸c˜oes est˜ao envolvidas, como • e × (que tamb´em pode ser representada pela concatena¸c˜ao dos operadores), existe outra propriedade: 6. Distributividade: a(b • c) = ab • ac e (a • b)c = ac • bc para todo a,b e c

pertencentes a S.

Para esses conjuntos foram desenvolvidos importantes elementos matem´aticos conhecidos como grupos, an´eis e corpos. Cada um deles ´e denotado pelo conjunto de elementos, as opera¸c˜oes definidas para esse conjunto e tamb´em pela gama de propriedades seguidas.

O grupo G, denotado por {G, •}, ´e um conjunto de elementos com uma opera¸c˜ao bin´aria, denotada por •, que associa a cada par (a, b) de elementos pertencentes a G um novo elemento (a • b) tamb´em pertencente a G. S˜ao obedecidas as propriedades de fechamento, associatividade, elemento identidade e o elemento inverso. Um exemplo de grupo ´e (N, +), na qual N ´e o conjunto dos n´umeros naturais e + ´e a opera¸c˜ao de adi¸c˜ao.

Se um grupo tem um n´umero finito de elementos, ele ´e chamado de grupo finito e a sua ordem ´e igual ao n´umero de elementos. Caso contr´ario, ele ´e dito ser um grupo infinito.

Um an´el R, denotado por {R, +, ∗}, ´e um conjunto de elementos com duas opera¸c˜oes bin´arias + e ∗, chamadas de adi¸c˜ao e multiplica¸c˜ao. Em rela¸c˜ao `a +, s˜ao obedecidas todas as propriedades de um grupo mais a comutatividade. J´a em rela¸c˜ao a ∗, apenas as propriedades de fechamento, associatividade e distribu-tividade s˜ao seguidas. O an´el ´e um conjunto com o qual ´e poss´ıvel fazer adi¸c˜ao, subtra¸c˜ao ( soma de um operando com o inverso aditivo do outro) e multiplica¸c˜ao sem sair do conjunto.

(17)

inverso em rela¸c˜ao `a ∗. Os conjuntos dos n´umeros racionais, reais e complexos s˜ao exemplos de corpos. Esses s˜ao exemplos de corpos infinitos, a criptografia h´a interesse apenas nos corpos de ordem finita.

Como os dados cifrados tamb´em precisam ser decifrados, ´e neces-s´ario que as opera¸c˜oes executadas durante a cifragem sobre o conjunto de dados de entrada, o bloco, sejam invers´ıveis para que possa ocorrer a decifragem. A exis-tˆencia da inversibilidade dentro de um conjunto usando as opera¸c˜oes de adi¸c˜ao e multiplica¸c˜ao ´e garantida apenas pelos corpos .

Um corpo finito de ordem p ´e um conjunto Zp de inteiros

{0, 1, ..., p − 1}, junto com opera¸c˜oes matem´aticas m´odulo p. Ele ´e denotado por GF (p),onde GF significa Galois Field em honra do matem´atico quem primeiro

es-tudou o assunto.

Como observado na sess˜ao anterior, um elemento de Zp s´o vai ter

uma inversa multiplicativa se ele for relativamente primo a p. Se p for primo, ent˜ao todos os elementos n˜ao zero de Zp ser˜ao relativamente primos a ele e todos ter˜ao

inversos multiplicativos.

Para achar a inversa multiplicativa de um n´umero dentro de um corpo, deve ser usado o algoritmo de Euclides.

O AES usa polinˆomios no qual os coeficientes est˜ao contidos em Zp

e os polinˆomios s˜ao definidos m´odulo um polinˆomio m(x) de ordem n.

2.3

Aritm´

etica Polinomial

No AES s˜ao feitas opera¸c˜oes modulares com polinˆomios. Os coe-ficientes desses polinˆomios fazem parte de um corpo finito. Desse modo ´e poss´ıvel fazer divis˜ao entre polinˆomios, uma vez que a divis˜ao entre dois polinˆomios ´e uma multiplica¸c˜ao de um polinˆomio pelo inverso do outro.

Em analogia `a aritm´etica inteira, n´os podemos escrever

f (x) mod g(x) como sendo o polinˆomio r(x), proveniente do resto da divis˜ao de f (x) por g(x).

(18)

14 adi¸c˜ao fica equivalente a opera¸c˜ao ou-exclusivo e a multiplica¸c˜ao `a ”E”. Ela s˜ao extremamente r´apidas de serem efetuadas em computadores.

Um polinˆomio f (x) sobre um corpo F ´e chamado de irredut´ıvel se e somente se f (x) n˜ao poder ser expressado como produto de dois polinˆomios, ambos sobre F , e ambos com grau menor que f (x). Polinˆomios irredut´ıveis tamb´em podem ser chamados de polinˆomios primos.

Na aritm´etica modular, ´e usado um corpo finito da forma GF (2n).

Fazer opera¸c˜oes polinomiais nesse tipo de corpo significa que os coeficientes v˜ao variar de 0 a 1 e que os polinˆomios ter˜ao grau de at´e n − 1. Isso acontece porque as opera¸c˜oes polinomiais s˜ao feitas m´odulo um polinˆomio irredut´ıvel de grau n. Todos os corpos finitos de uma dada ordem s˜ao isom´orficos, isto ´e, mesmo mudando o polinˆomio irredut´ıvel usado no opera¸c˜ao modular, mas mantendo sua ordem, os elementos do corpo ser˜ao os mesmos.

Um polinˆomio f (x) em GF (2n) f (x) = an−1xn−1+ an−2xn−2+ ... + a1x + a0 = n−1 X i=0 aixi

pode ser representado unicamente pelos seus coeficientes bin´arios (an−1an−2...a0). Portanto, um polinˆomio em GF (2n) pode ser representado por um

n´umero bin´ario de tamanho n.

A adi¸c˜ao de polinˆomios corresponde a somar os coeficientes corres-pondentes, e, no caso de polinˆomios em Z2, adi¸c˜ao ´e apenas a opera¸c˜ao ou-exclusivo.

Ent˜ao, a adi¸c˜ao entre dois polinˆomios em GF (2n) corresponde a um opera¸c˜ao

ou-exclusivo bit a bit.

A multiplica¸c˜ao n˜ao ´e t˜ao simples quanto a adi¸c˜ao, mas existe um t´ecnica que a simplifica bastante. Essa t´ecnica ser´a explicada com referˆencia a

GF (28)usando o polinˆomio x8+ x4+ x3+ x + 1, que ´e o corpo finito usado no AES.

A multiplica¸c˜ao de dois polinˆomios consiste em v´arias multiplica-¸c˜oes do primeiro operando por x e em somas dos resultados intermedi´arios,por exem-plo:

(19)

A multiplica¸c˜ao de um polinˆomio por x dentro do corpo finito es-pecificado anteriormente pode ser implementada como um deslocamento de 1 bit a esquerda seguido de um ou-exclusivo bit a bit com o n´umero 00011011, que representa o polinˆomio x4 + x3 + x + 1. Essa t´ecnica ´e baseada no fato de que

x8mod x8+ x4+ x3+ x + 1 = x4 + x3 + x + 1. Se o resultado da multiplica¸c˜ao de

(20)

Cap´ıtulo 3

O AES

O AES ´e um algoritmo constitu´ıdo por v´arias rodadas. Cada rodada ´e composta por 4 transforma¸c˜oes, uma de permuta¸c˜ao e trˆes de substitui¸c˜ao:

1. ByteSub: usa uma tabela de substitui¸c˜ao para substituir byte por byte do bloco;

2. ShiftRow: uma permuta¸c˜ao simples atrav´es deslocamento de linhas; 3. MixColumn: uma substitui¸c˜ao que usa aritm´etica sobre GF (28);

4. AddRoundKey: aplica¸c˜ao de ou-exclusivo entre o bloco e a chave.

O n´umero de rodadas ´e vari´avel e dependente do tamanho da chave. S˜ao 10 rodadas para chave de 128 bits, 12 para 192 bits e 14 para 256 bits.

A ´ultima rodada n˜ao cont´em a transforma¸c˜ao MixColumn, que foi retirada para que fosse poss´ıvel montar o algoritmo inverso ao AES, que ´e usado na decifragem. A estrutura do AES inverso pode ser visualisada na figura 3.1.

Antes da primeira rodada ´e feita uma AddRoundKey. Apenas a AddRoundKey faz uso da chave. Qualquer outra opera¸c˜ao, aplicada no fim ou no come¸co, ´e revers´ıvel sem conhecimento da chave e portanto, n˜ao adiciona seguran¸ca ao algoritmo.

A seq¨uˆencia de passos pode ser visualizada na figura 3.1.

(21)

Figura 3.1: Estrutura do AES

3.1

ByteSub

Essa transforma¸c˜ao consiste em substituir cada byte do bloco por outro byte, que ´e obtido consultando a caixa-S. Ela ´e uma matriz 16×16 que cont´em todos os 256 poss´ıveis valores de 8 bits.

(22)

18 4 bits do byte s˜ao usados como valor da linha da matrix e os outros 4 bits como valor para a coluna. A figura 3.2 ilustra essa substitui¸c˜ao.

Figura 3.2: ByteSub [1]

Essa transforma¸c˜ao provˆe a n˜ao linearidade do cifrador. A caixa-S ´e derivada da fun¸c˜ao inversa sobre GF (28), conhecida por ter boas propriedades

n˜ao-lineares. Essa fun¸c˜ao pode ser representada por uma fun¸c˜ao alg´ebrica muito simples, o que permite fazer manipula¸c˜oes alg´ebricas facilmente. Essa maniputa¸c˜oes podem ser usadas para montar ataques como os ataques de interpola¸c˜ao. Para contornar isso, essa fun¸c˜ao ´e combinada com uma transforma¸c˜ao affine invers´ıvel simples. As duas fun¸c˜oes combinadas formam uma express˜ao alg´ebrica complexa, que inibe os ataques [4]. A constru¸c˜ao da caixa-S ´e descrita nos seguintes passos:

1. A caixa-S ´e inicializada com valores de bytes seguindo uma seq¨uˆencia ascen-dente linha por linha. A primeira linha cont´em os valores 00, 01, ..., 0F ; a segunda cont´em 10, 11, ..., 1F ; e assim por diante;

2. Cada byte na caixa-S ´e mapeado para o seu inverso multiplicativo no corpo finito GF (28);

3. ´E aplicada uma transforma¸c˜ao affine particular . Essa transforma¸c˜ao foi es-colhida de modo. Dado um byte rotulado como b7b6b5b4b3b2b1b0, a opera¸c˜ao

escolhida foi:

(23)

onde ci ´e um i-´esimo bit da constante 01100011 e o sinal ( 0

) significa que a vari´avel ser´a atualizada com o valor da direita. Ela tamb´em pode ser repre-sentada pela multiplica¸c˜ao das matrizes:

                    b00 b01 b02 b03 b04 b05 b06 b07                     =                     1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1                                         b0 b1 b2 b3 b4 b5 b6 b7                     +                     1 1 0 0 0 1 1 0                     (3.2)

Para a decifragem ´e usada a opera¸c˜ao InvSubBytes, que ´e seme-lhante a SubByte, por´em usa uma caixa-S inversa. Essa caixa-S inversa ´e contru´ıda aplicando o inverso multiplicativo no corpo finito GF (28) `a caixa-S usanda na

cifra-gem em conjunto da transforma¸c˜ao affine inversa:

b0i = b(i+2)mod 8⊕ b(i+5)mod 8⊕ b(i+7)mod 8⊕ di

onde d ´e 00000101. Cuja representa¸c˜ao matricial ´e:

(24)

20

3.2

ShiftRow

Essa transforma¸c˜ao consiste em deslocalar as linhas do bloco ci-clicamente para a esquerda. O n´umero de deslocamentos varia de acordo com a linha. A primeira linha n˜ao ´e deslocada, a segunda ´e deslocada uma posi¸c˜ao, a segunda duas e a terceira posi¸c˜oes. Dessa forma, cada coluna do bloco de sa´ıda ´e composta por bytes de todas as colunas do bloco de entrada. A figura 3.3 ilustra essa transforma¸c˜ao.

Figura 3.3: ShifRow [1]

A transforma¸c˜ao inversa `a ShiftRow ´e chamada de InvShiftRow. Ela ´e semelhante `a ShiftRow, por´em o sentido do deslocamento ´e o inverso, para a direita.

3.3

MixColumn

Essa transforma¸c˜ao opera em cada coluna individualmente. Cada byte da coluna ´e mapeado a um novo valor que ´e uma fun¸c˜ao de todos os quatro bytes da coluna (Figura 3.4).

A tranforma¸c˜ao pode ser definida atrav´es da multiplica¸c˜ao das

ma-trizes:        02 03 01 01 01 02 03 01 01 01 02 03 03 01 01 02                 s0,0 s0,1 s0,2 s0,3 s1,0 s1,1 s1,2 s1,3 s2,0 s2,1 s2,2 s2,3 s3,0 s3,1 s3,2 s3,3         =         s00,0 s00,1 s00,2 s00,3 s01,0 s01,1 s01,2 s01,3 s02,0 s02,1 s02,2 s02,3 s03,0 s03,1 s03,2 s03,3        

(25)

Figura 3.4: MixColumn [1]

GF (28). A transforma¸c˜ao MixColumn em uma coluna ´e expressada como:

s00,j = (2 • s0,j) ⊕ (3 • s1,j) ⊕ s2,j ⊕ s3,j

s01,j = s0,j ⊕ (2 • s1,j) ⊕ (3 • s2,j) ⊕ s3,j

s02,j = s0,j ⊕ s1,j⊕ (2 • s2,j) ⊕ (3 • s3,j)

s03,j = (3 • s0,j) ⊕ s1,j ⊕ s2,j⊕ (2 • s3,j)

(3.4)

Essa transforma¸c˜ao est´a fundamentada em multiplica¸c˜oes de linˆomios. Cada elemento de uma coluna se transforma nos coeficientes de um po-linˆomio, que ent˜ao ´e multiplicado pelo polinˆomio c(x)(Equa¸c˜ao 3.5) m´odulo x4 + 1

sobre GF (28).

c(x) =8 030x3+8010x2+8010x +8 020 (3.5)

Esse polinˆomio ´e coprimo a x4+ 1 e portanto invers´ıvel.

3.4

AddRoundKey

(26)

22

Figura 3.5: AddRoundKey [1]

3.5

Deriva¸c˜

ao de chave

O algoritmo de deriva¸c˜ao de chave usado na AES consiste em uma fase de expan¸c˜ao e outra de sele¸c˜ao. Na fase de expan¸c˜ao a chave mestra de 128 bits ´e expandida para uma chave de 1408 bits. Essa deriva¸c˜ao ´e descrita pelo seguinte algoritmo na linguagem C:

KeyExpansion(byte MasterKey[16], word W[44]) { for(i = 0; i < 4; i++) W[i] = (MasterKey[4*i],MasterKey[4*i+1],MasterKey[4*i+2],MasterKey[4*i+3]); for(i = 4; i < 44; i++) { temp = W[i - 1]; if (i % 4 == 0)

temp = SubByte(RotByte(temp)) ^ Rcon[i / 4]; W[i] = W[i - 4] ^ temp;

} }

(27)

se tranforma em (b,c,d,a). Rcon ´e um conjunto de constantes que s˜ao adicionadas `as subchaves. Para cada subchave, uma constante diferente ´e adicionada, o que previne a cria¸c˜ao de chaves fracas, como acontecia no DES. Na deriva¸c˜ao de chave do DES era poss´ıvel criar chaves de modo que a cifragem e a decifragem produzissem resultados iguais. A figura 3.6 ilustra os passos:

RC

ByteSub

Figura 3.6: Deriva¸c˜ao de chave

A fase de sele¸c˜ao ´e simples. As subchaves s˜ao retiradas da chave expandida sequencialmente, a primeira subchave ´e composta do bit 0 at´e bit 127, a segunda subchave do bit 128 at´e o 255, e assim por diante.

(28)

24 W[5] = W[4] ^ W[1] W[6] = W[5] ^ W[2] W[7] = W[6] ^ W[3] . . . W[40] = SubByte(RotByte(W[39])) ^ W[36] ^ Rcon[10] W[41] = W[40] ^ W[37] W[42] = W[41] ^ W[38] W[43] = W[42] ^ W[39]

O algoritmo de deriva¸c˜ao de chave foi montado de forma que ´e pos-s´ıvel restaurar a chave mestra atrav´es de qualquer subchave. Para isso, ´e necess´ario seguir o caminho inverso da deriva¸c˜ao. A chave mestra corresponde aos primeiros 128 bits da chave estendida. O algoritmo inverso ´e:

InverseKeyExpansion(byte SubKey[16], word W[4*NUMERO_DE_RODADAS], MasterKey[16]) {

for(i = 0,j = 4*NUMERO_DE_RODADAS; i < 4; i++,j++)

W[j] = (SubKey[4*i],SubKey[4*i+1],SubKey[4*i+2],SubKey[4*i+3]); for(j -= 5; j >= 0; j--) { if (j % 4 == 0){ W[j] = ByteSub(RotByte(W[j+3])) ^ W[j+4]; W[j] ^= Rcon[j / 4]; }else{ W[j] = W[j+3] ^ W[j+4]; } } for(i = 12,j = 3; i >= 0; i-=4,j--) (MasterKey[i],MasterKey[i+1],MasterKey[i+2],MasterKey[i+3]) = w[j] }

(29)

W[43] = (Subkey[12],Subkey[13],Subkey[14],Subkey[15]) W[42] = (Subkey[8],Subkey[9],Subkey[10],Subkey[11]) W[41] = (Subkey[4],Subkey[5],Subkey[6],Subkey[7]) W[40] = (SubKey[0],Subkey[1],Subkey[2],Subkey[3]) W[36] = SubByte(RotByte(W[39])) ^ W[40] ^ Rcon[10] W[37] = W[40] ^ W[41] W[38] = W[41] ^ W[42] W[39] = W[42] ^ W[43] . . . W[3] = (Subkey[12],Subkey[13],Subkey[14],Subkey[15]) W[2] = (Subkey[8],Subkey[9],Subkey[10],Subkey[11]) W[1] = (Subkey[4],Subkey[5],Subkey[6],Subkey[7]) W[0] = (Subkey[0],Subkey[1],Subkey[2],Subkey[3])

(30)

Cap´ıtulo 4

O Ataque Quadrado

O ataque quadrado ´e uma t´ecnica muito efetiva de criptoan´alise para cifradores de bloco. Ele foi concebido como uma t´ecnica dedicada ao algoritmo Square, mas tamb´em pode ser usada nos cifradores Rijndael (AES), Twofish e IDEA. Ele ´e o melhor ataque conhecido contra o AES.

Diferentes vers˜oes desse ataque foram desenvolvidas, variando a ordem do ataque e o n´umero de rodadas do cifrador. A ordem do ataque diz respeito ao n´umero de bytes do bloco que s˜ao saturados. Ser˜ao analisados os ataques de primeira ordem para 4 rodadas [6] e 6 rodadas [7] e o ataque de quarta ordem para 5 rodadas [8].

(31)

4.1

Ataque de primeira ordem sobre 4 rodadas

A descri¸c˜ao desse ataque ´e baseada em [6].

Considere a representa¸c˜ao matricial 4 × 4 do bloco de entrada do cifrador:         a0,0 a0,1 a0,2 a0,3 a1,0 a1,1 a1,2 a1,3 a2,0 a2,1 a2,2 a2,3 a3,0 a3,1 a3,2 a3,3         (4.1)

O ataque consiste em criar um conjunto de 256 blocos que s˜ao diferentes entre si em apenas uma posi¸c˜ao, no elemento a0,0. Essa posi¸c˜ao assume

todos os valores poss´ıveis de um byte, de 0 at´e 255, cada bloco com um valor. As outras 15 posi¸c˜oes assumem o mesmo valor em qualquer bloco do conjunto. Posi¸c˜oes diferentes podem ter valores distintos, o que se mant´em constante ´e o valor em cada posi¸c˜ao espec´ıfica. Esse conjunto se chama conjunto integral ou conjunto Λ. A posi¸c˜ao que assume os valores diferentes se chamada posi¸c˜ao saturada ou ativa, e ´e representada pela letra p, de permuta¸c˜ao. As posi¸c˜oes que n˜ao tˆem o valor mudado s˜ao representadas pela letra c, de constante. A representa¸c˜ao do bloco fica assim:

                       p c c c c c c c c c c c c c c c         i : i = 0, 1, ..., 255                (4.2)

Nas subsess˜oes seguinte ser˜ao mostradas as transforma¸c˜oes que o conjunto integral sofre durante as 4 rodadas da cifragem. Para tal, os quatro blocos:

|00 00 00 00| |01 00 00 00| |02 00 00 00| |03 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00| |00 00 00 00|

de texto em claro ser˜ao tidos como exemplo para mostrar a evolu¸c˜ao dos blocos durante a cifragem. A chave usada ser´a:

(32)

28 Tanto a escolha dos quatro blocos de texto quanto a escolha da chave n˜ao tiveram motivo em especial. Esses dados podem ser escolhidos aleatoria-mente.

4.1.1

1

a

Rodada

A aplica¸c˜ao inicial de AddRoundKey n˜ao altera a estrutura do con-junto integral, apenas muda o valor das posi¸c˜oes constantes e muda a ordem dos valores da posi¸c˜ao saturada, que continua tendo todos os 256 valores dentro do conjunto:

|01 89 01 89| |00 89 01 89| |03 89 01 89| |02 89 01 89| |23 AB 23 AB| |23 AB 23 AB| |23 AB 23 AB| |23 AB 23 AB| |45 CD 45 CD| |45 CD 45 CD| |45 CD 45 CD| |45 CD 45 CD| |67 EF 67 EF| |67 EF 67 EF| |67 EF 67 EF| |67 EF 67 EF|

A ordem dessas valores n˜ao importa, pois trata-se de um conjunto e n˜ao de uma sequˆencia ordenada.

A transforma¸c˜ao ByteSub ´e uma fun¸c˜ao injetora, o que faz com que a sua aplica¸c˜ao ao conjunto integral n˜ao altere a estrutura do conjunto. A posi¸c˜ao saturada sofrer´a apenas uma permuta¸c˜ao e as posi¸c˜oes constantes ter˜ao seus valores trocados:

                       p c c c c c c c c c c c c c c c         i : i = 0, 1, ..., 255                (4.3)

O estado dos blocos fica:

|7C A7 7C A7| |63 A7 7C A7| |7B A7 7C A7| |77 A7 7C A7| |26 62 26 62| |26 62 26 62| |26 62 26 62| |26 62 26 62| |6E BD 6E BD| |6E BD 6E BD| |6E BD 6E BD| |6E BD 6E BD| |85 DF 85 DF| |85 DF 85 DF| |85 DF 85 DF| |85 DF 85 DF|

A transforma¸c˜ao ShiftRow apenas troca a localiza¸c˜ao dos bytes:

|7C A7 7C A7| |63 A7 7C A7| |7B A7 7C A7| |77 A7 7C A7| |62 26 62 26| |62 26 62 26| |62 26 62 26| |62 26 62 26| |6E BD 6E BD| |6E BD 6E BD| |6E BD 6E BD| |6E BD 6E BD| |DF 85 DF 85| |DF 85 DF 85| |DF 85 DF 85| |DF 85 DF 85|

(33)

em outra linha, ela seria deslocada, mas isso nada afeta a estrutura do conjunto integral.

A transforma¸c˜ao MixColumn muda toda a coluna que cont´em a posi¸c˜ao saturada. Isso faz com que os outros 3 bytes da coluna passem a ser fun¸c˜ao da posi¸c˜ao saturada. Mas n˜ao faz com que a posi¸c˜ao saturada pare de assumir os 256 valores poss´ıveis.

Para melhor explicar o efeito da MixColumn, a considere como sendo a fun¸c˜ao MC(x, y, z, w), onde x,y,z e w s˜ao as posi¸c˜oes de uma coluna. No caso da primeira coluna, a MC vai receber como parˆametro uma permuta¸c˜ao e trˆes constantes: MC(p,c,c,c). Como apenas o parˆametro p muda entre os blocos, o resultado do MC vai depender apenas de p. Variando todos os valores poss´ıveis das entradas, 28.20.20.20, o conjunto imagem ser´a igual a p. Nas posi¸c˜oes onde os

quatro parˆametros s˜ao constantes, MC(c, c, c, c), a imagem ser´a uma constante:                        MC(p, c, c, c) MC(c, c, c, c) MC(c, c, c, c) MC(c, c, c, c) MC(p, c, c, c) MC(c, c, c, c) MC(c, c, c, c) MC(c, c, c, c) MC(p, c, c, c) MC(c, c, c, c) MC(c, c, c, c) MC(c, c, c, c) MC(p, c, c, c) MC(c, c, c, c) MC(c, c, c, c) MC(c, c, c, c)         i         p c c c p c c c p c c c p c c c         i : i = 0, 1, ..., 255                (4.4) Os blocos se tornaram: |EF 07 EF 07| |D1 07 EF 07| |E1 07 EF 07| |F9 07 EF 07| |D5 B2 D5 B2| |CA B2 D5 B2| |D2 B2 D5 B2| |DE B2 D5 B2| |B8 74 B8 74| |A7 74 B8 74| |BF 74 B8 74| |B3 74 B8 74| |2D 78 2D 78| |0C 78 2D 78| |24 78 2D 78| |30 78 2D 78|

A transforma¸c˜ao AddRoundKey, como foi dito anteriormente, n˜ao altera a estrutura do conjunto integral, apenas faz uma permuta¸c˜ao da posi¸c˜ao saturada:

|8D EC 05 64| |B3 EC 05 64| |83 EC 05 64| |9B EC 05 64| |4B 87 C3 0F| |54 87 C3 0F| |4C 87 C3 0F| |40 87 C3 0F| |22 23 AA AB| |3D 23 AA AB| |25 23 AA AB| |29 23 AA AB| |ED 57 65 DF| |CC 57 65 DF| |E4 57 65 DF| |F0 57 65 DF|

4.1.2

2

a

Rodada

A transforma¸c˜ao ByteSub apenas muda o valor de cada byte, man-tendo a estrutura do conjunto:

(34)

30 A trasforma¸c˜ao ShiftRow desloca as posi¸c˜oes saturadas, fazendo com que toda coluna contenha uma posi¸c˜ao saturada:

                       p c c c c p c c c c p c c c c p         i : i = 0, 1, ..., 255                (4.5) |5D CE 6B 43| |6D CE 6B 43| |EC CE 6B 43| |14 CE 6B 43| |17 2E 76 B3| |17 2E 76 20| |17 2E 76 29| |17 2E 76 09| |AC 62 93 26| |AC 62 27 26| |AC 62 3F 26| |AC 62 A5 26| |9E 55 5B 4D| |9E 4B 5B 4D| |9E 69 5B 4D| |9E 8C 5B 4D|

A trasforma¸c˜ao MixColumn opera sobre cada coluna separada-mente e faz com que todas as posi¸c˜oes do bloco se tornem saturadas:

                       p p p p p p p p p p p p p p p p         i : i = 0, 1, ..., 255                (4.6) |B1 C2 84 23| |D1 DC 30 8D| |C8 FE 28 96| |23 1B B2 F6| |02 61 72 19| |32 7F B5 24| |B3 5D 9D 36| |4B B8 28 76| |B0 DB CD 6B| |80 F9 BE F8| |01 9F 8E F1| |F9 AB A1 D1| |7B AF EE CA| |2B 93 5A 59| |B3 D7 42 50| |A0 06 D8 70|

Como foi dito anteriormente, a transforma¸c˜ao AddRoundKey n˜ao muda a estrutura do conjunto. Portanto, depois de duas rodadas do AES, cada um dos 16 bytes de cada bloco est´a saturado.

|AB 33 9F 5B| |CB 2D 2B F5| |D2 0F 33 EE| |39 EA A9 8E| |02 54 51 87| |32 4A 96 BA| |B3 68 BE A8| |4B 8D 0B E8| |76 4A 4E 37| |46 68 3D A4| |C7 0E 0D AD| |3F 3A 22 8D| |40 BB B2 31| |10 87 06 A2| |88 C3 1E AB| |9B 12 84 8B|

4.1.3

3

a

Rodada

Foi visto no passo anterior que as transforma¸c˜oes ByteSub, Shift-Row e AddRoundKey n˜ao alteram a estrutura do conjunto integral. O mesmo n˜ao acontece com a transforma¸c˜ao MixColumn.

(35)

elementos v˜ao variar de acordo com a posi¸c˜ao saturada. Como um elemento saturado pode ter 28 valores, os outros trˆes valores tamb´em v˜ao variar nessa faixa.

At´e a segunda rodada existia no m´aximo um elemento saturado em cada posi¸c˜ao da coluna, o que fazia com que a conjunto integral n˜ao perdesse sua estrutura. Mas nessa rodada, todos os elementos das colunas est˜ao saturados. Logo, cada elemento de uma coluna tem como valor o resultado da MC com os quatro parˆametros variando:

        MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p) MC(p, p, p, p)         i         b b b b b b b b b b b b b b b b         i : i = 0, 1, ..., 255 (4.7) A varia¸c˜ao dos quatro valores, (28.28.28.28), resulta em 232poss´ıveis

combina¸c˜oes. Essa combina¸c˜oes retornam 232 resultados, sendo 28 valores distintos

distribuidos de forma n˜ao uniforme. Como existe apenas 28 blocos, 232− 28

resul-tados n˜ao aparecer˜ao, apenas os primeiros 28. Como a distribui¸c˜ao dos valores dos

resultados n˜ao ´e uniforme, vai acontecer de valores aparecerem repetidos e outros valores n˜ao aparecem. Logo, a estrutura do conjunto integral ´e perdida.

Nessa rodada, apesar da estrutura do conjunto integral ter sido quebrada, existe uma propriedade que n˜ao ´e afetada por transforma¸c˜oes lineares e ser´a usada como base para o ataque. Essa propriedade ´e o balan¸co, que ´e a soma dos elementos de mesma posi¸c˜ao do conjunto integral. A seguinte equa¸c˜ao formaliza esse conceito:

a0i,j⊕ a1i,j ⊕ ... ⊕ a255i,j

255

X

k=0

aki,j = 0 (4.8)

O somat´orio ´e o ou-exclusivo dos termos. Em qualquer posi¸c˜ao do bloco cada bit assume o valor 1 exatamente 128 vezes, fazendo com que a aplica¸c˜ao do ou-exclusivo resulte em 0 bit a bit. Logo, todas as posi¸c˜oes do conjunto integral est˜ao balanceadas. Quanto `a transforma¸c˜ao AddRoundKey, ela tamb´em n˜ao altera o balan¸co, pois a mesma subchave ´e aplicada a todos os blocos do conjunto. Portanto, depois de 3 rodadas do AES, todas as posi¸c˜oes dos blocos est˜ao balanceada. Os estado dos blocos exemplares depois da ByteSub, ShiftRow, MixColumn e AddRoundKey, respectivamente, s˜ao:

(36)

32 |09 EA 37 C7| |CA 17 6F 3A| |C4 2E 72 62| |14 C9 5F 3D| |62 C3 DB 39| |1F D8 F1 E6| |B5 76 C3 28| |12 87 D3 19| |20 D1 17 77| |D6 90 F4 23| |45 AE C2 6D| |5D 2B 9B B3| |2F 9A 38 D6| |27 49 5A 45| |D7 95 C6 AB| |93 5D 75 80| |C7 09 EA 37| |3A CA 17 6F| |62 C4 2E 72| |3D 14 C9 5F| |4C 66 46 0A| |42 83 B3 98| |0B 54 28 3E| |6D 21 B7 23| |94 C6 57 81| |FB F2 FB 00| |3F 51 23 66| |3B 22 A8 A0| |4E 26 99 A0| |C9 9F 88 FE| |E3 BE E4 9E| |35 2A E2 50| |3C 07 96 84| |A4 25 88 89| |92 32 06 5A| |82 CC 09 A6| |59 82 B9 8D| |57 67 4C 1F| |1E B0 D7 B9| |78 C5 48 A4| |DE B9 0B 43| |B1 8D A7 C2| |75 2E 7F A4| |71 5D F4 62| |87 7E 42 27| |00 C7 53 79| |2A E6 3F 19| |FC 72 39 D7| |BB 94 59 B0| |23 B6 47 BD| |15 A1 C9 6E| |05 5F C6 92|

4.1.4

4

a

Rodada

Essa rodada ´e a ´ultima nesse ataque e portanto consiste apenas nas transforma¸c˜oes ByteSub, ShiftRow e AddRoundKey.

Considerando h como o resultado do terceiro passo, o quarto passo pode ser representado pela seguinte equa¸c˜ao:

z ≡ Shif tRow(ByteSub(h)) ⊕ K4 (4.9)

onde K4 ´e a subchave utilizada no quarto passo.

´

E poss´ıvel escrever o resultado do terceiro passo da seguinte ma-neira:

h = InvByteSub(InvShif tRow(z ⊕ K4))

= InvByteSub(InvShif tRow(z) ⊕ InvShif tRow(K4)) (4.10)

Esse processo pode ser visualizado pela figura B.1.

Como foi visto anteriormente, todas as posi¸c˜oes de h s˜ao balance-adas. Logo, para a subchave K4 correta, todas as posi¸c˜oes de h (Equa¸c˜ao B.9) s˜ao

balanceadas. Caso a subchave seja incorreta, o balan¸co em uma posi¸c˜ao qualquer ser´a incorreto, isto ´e, diferente de zero. Uma subchave incorreta pode produzir um balan¸co correto com a probabilidade de 1

256, pois existem 256 valores poss´ıveis para

um byte e o zero ´e um deles.

(37)
(38)

34 sume em buscar exaustivamente a chave usada na cifragem testando a sua corretude atrav´es do balan¸co do conjunto integral.

O ataque come¸ca com a obtens˜ao dos blocos do conjunto integral cifrados. Seja zk o k-´esimo bloco do conjunto integral cifrado. ´E fixado um byte

zk

i,j e tenta-se encontrar o valor ki,j4 , que ´e o byte da subchave usado na cifragem

desse bloco. Para isso, primeiro ´e dado um valor aleat´orio a k4

i,j e depois ´e feita

a transforma¸c˜ao InvShiftRow sobre zk

i,j e k4i,j, e em seguida ´e aplicado InvByteSub

sobre o ou-exclusivo desses dois resultados. Repete-se o processo para todos os blocos do conjunto integral, calcula-se o ou-exclusivo dos resultados e testa-se se a soma ´e zero.

A opera¸c˜ao InvShiftRow pode ser contornada da seguinte forma: [InvShif tRow(zk)]i,j = zi,(4−i+j)mod 4k (4.11)

o que resume a procura do byte da subchave a verificar se a seguinte igualdade ´e v´alida: 255 X k=0 S−1[zk i,(4−i+j)mod 4⊕ ki,j] = 0 (4.12)

onde S−1 ´e a caixa-S inversa. Se a igualdade for v´alida, o valor de k4

i,j est´a certo,

caso contr´ario, o valor de k4

i,j est´a errado e ´e dado um novo valor para ele e todo o

processo ´e repetido. Como foi dito anteriormente, esse teste pode retornar um valor errado com probabilidade de 1

256. O que pode ser feito ´e usar um segundo conjunto

integral no processo, o que diminui a chance de erro para 1 − 2−16. Para obter o

resto de K4 basta repetir o procedimento para os outros bytes.

Atrav´es desse ataque foi poss´ıvel obter a subchave K4. Para obter

a chave mestra ´e necess´ario inverter o processo de deriva¸c˜ao de chave, descrito na sess˜ao 3.5.

A complexidade desse ataque ´e equivalente a 215(24.28.28.2

24.22 ) cifragens

usando 29 textos escolhidos. Esse resultado ´e obtido atrav´es da multiplica¸c˜ao do

n´umero de bytes da chave a serem encontrados(24) pela faixa de valores poss´ıveis

de um byte da chave(28), pelo n´umero de indexa¸c˜oes da caixa-S para cada byte da

(39)

de indexa¸c˜oes presentes em uma cifragem com 4 rodadas(26).

complexidade = ((no de bytes da chave) × (f aixa de valores da chave) × (node indexacoes para cada tentativa de chave)) × (node conjuntos integrais)

÷ ((indexacoes por rodada) × (node rodadas))

(4.13)

4.2

Ataque de primeira ordem sobre 6 rodadas

Esse ataque ´e basicamente o ataque sobre 4 rodadas com duas ex-ten¸c˜oes, uma nova rodada no final do cifrador e a outra no in´ıcio. Nas pr´oximas sess˜oes ser˜ao explicadas as extens˜oes e como elas s˜ao combinadas para formar o ataque ao AES com 6 rodadas.

4.2.1

Extens˜

ao no final

Essa extens˜ao consiste em adicionar uma nova rodada no final do cifrador, que o deixa com 5 rodadas. O ataque ´e fundamentado sobre o mesmo prin-c´ıpio que o anterior, decifrar o texto cifrado at´e que os blocos estejam balanceados, o que ´e uma caracter´ıstica dos blocos cifrados com 3 rodadas. Portanto, nesse ataque ´e necess´ario decifrar duas rodadas do AES.

Considerando h como o resultado da terceira rodada, z o resultado do quarta rodada e p o resultado da quinta rodada, ´e poss´ıvel escrever h da seguinte maneira:

h = InvByteSub(InvShif tRow(InvM ixColumn(z)) ⊕ InvShif tRow(InvM ixColumn(K4)))

z = InvByteSub(InvShif tRow(p) ⊕ InvShif tRow(K5))

(4.14) O processo pode ser visualizado pela figura B.2.

(40)

36

(41)

pertencentes `a mesma coluna. S˜ao necess´arios 4 bytes da quinta subchave , porque o resultado da InvMixcolumn depende dos 4 bytes da coluna.

A equa¸c˜ao que representa a relac˜ao posicional entre um byte de h e cada byte da 5-tupla ´e:

hi,j → (Ki,(4−i+j)mod44 , Ki,(8−2i+j)mod45 , Ki+1,(8−2i+j)mod45 , Ki+2,(8−2i+j)mod45 , Ki+3,(8−2i+j)mod45 )

(4.15) A complexidade desse ataque ´e de 237,7(4.232.(4+28.4)

24.5 ) cifragens e 232

textos escolhidos. Esse n´umero foi obtido pela seguinte equa¸c˜ao:

complexidade = ((node colunas da chave) × (f aixa de valores da coluna)

× ((node indexacoes na quinta rodada)

+ (f aixa de valores de um byte da chave da quarta rodada)

× (node indexaes na quarta rodada)))

÷ ((indexacoes por rodada) × (node rodadas))

(4.16)

4.2.2

Extens˜

ao no in´ıcio

Nessa estens˜ao, o ataque acima ´e extendido com mais uma rodada, mas dessa vez no in´ıcio do algoritmo. Isso faz com que o ataque tenha efic´acia sobre um AES de 6 rodadas.

O conjunto de entrada deve ser escolhido de modo que o resultado da primeira rodada seja igual `a entrada do ataque de 5 rodadas descrito anteri-ormente, isto ´e, um conjunto integral dos quais uma posi¸c˜ao dos blocos deve ser uma permuta¸c˜ao e as outra devem ser constantes. Para isso, ´e necess´ario usar um conjunto de entrada de 232 blocos com 4 posi¸c˜oes saturadas.

As posi¸c˜oes dos elementos saturandos deve ser tal que, ao passar pela ShiftRow, eles pertencer˜ao a mesma coluna. Essa coluna conter´a o elemento saturado no final da rodada. Quando esses 232 blocos s˜ao cifrados pela rodada

adicional, eles produzirem 232 blocos dos quais pode ser selecionado um conjunto

integral. ´E poss´ıvel selecionar 28 diferentes conjuntos integrais.

(42)

38 atrav´es de busca exaustiva. Para cada quadrupla de bytes testados, ´e necess´ario rodar o ataque anterior.

A complexidade do ataque ´e 269.7(232.237.7) cifragens e 232 textos

escolhidos. Esse resultado ´e obtido atrav´es da multiplica¸c˜ao da faixa de bytes a serem testados nos 4 bytes da primeira subchave(232) pela complexidade do ataque

anterior(237.7).

Esse processo pode ser visualizado pela figura B.3.

(43)

4.3

Ataque de quarta ordem sobre 5 rodadas

Esse ataque ´e composto pelos mesmos passos que o ataque de pri-meira ordem sobre 4 rodadas, mas com um conjunto de blocos de entrada diferente, um conjunto integral de quarta ordem. Isso significa que o conjunto cont´em quatro elementos saturados. Esses 4 bytes podem ser vistos como uma word que varia de 0 a 232 − 1. Logo, para o conjunto integral conter todos os valores poss´ıveis s˜ao

necess´arios 232 blocos.

Para explicar a importˆencia desse ataque ´e necess´ario explicar o conceito de invariante. O invariante de um algoritmo ´e a parte do algoritmo cujo comportamento ´e poss´ıvel prever, ´e a parte at´e a qual estrutura dos blocos de entrada n˜ao ´e perdida. O objetivo de um cifrador ´e acabar com qualquer estrutura que os blocos de entrada possam ter, fazendo com que a sa´ıda do cifrador seja semelhante a um gerador de n´umeros aleat´orios. Logo, quanto menor o invariante de cifrador, melhor ele ´e.

Com o uso de um conjunto integral de quarta ordem o invariante do cifrador avan¸ca mais uma rodada, permitindo extender o ataque ao AES a 5 rodadas. Esse avan¸co ´e poss´ıvel porque o conjunto consegue passar pelo terceiro MixColumn sem perder a sua estrutura. As propriedades do MixColumn referente a isso foram explicadas na subsess˜ao B.2.1.3.

A complexidade desse ataque ´e equivalente a 238.7(24.28.232.2

24.5 )

cifra-gens usando 233 textos escolhidos. Esse resultado ´e obtido atrav´es da multiplica¸c˜ao

do n´umero de bytes da chave a serem encontrados(24) pela faixa de valores poss´ıveis

de um byte da chave(28), pelo n´umero de indexa¸c˜oes da caixa-S para cada byte da

chave(232) e pelo n´umero de vezes que tudo isso ´e feito(2), tudo divido pelo n´umero

de indexa¸c˜oes presentes em uma cifragem com 5 rodadas(24.5).

complexidade = ((no de bytes da chave) × (f aixa de valores da chave)

× (node indexacoes para cada tentativa de chave))

× (node conjuntos integrais)

÷ ((indexacoes por rodada) × (node rodadas))

(44)

Cap´ıtulo 5

Considera¸c˜

oes Finais e Trabalhos

Futuros

Esse trabalho conseguiu atingir todos os objetivos definidos. Com os estudos feitos nesse trabalho foi poss´ıvel por em pr´atica as pesquisas feitas pelo Labsec na ´area de criptoan´alise e expandir os conhecimentos sobre criptografia e suas fundamenta¸c˜oes matem´aticas.

A dificuldade enfrentada no desenvolvimento das an´alises compu-tacionais foi a grande complexidade dos algoritmos de criptoan´alise, que requerem uma grande capacidade de processamento, as vezes at´e proibitiva. Alguns testes implementados podem demorar horas para serem conclu´ıdos. N˜ao foi poss´ıvel im-plementar ataques sobre um maior n´umero de rodadas do AES, pois eles demandam uma grande capacidade de processamento e tempo, os quais n˜ao estavam dispon´ıveis para o desenvolvimento desse trabalho.

Esse trabalho pode ser expandido visando amenizar o problema apresentado a cima. As solu¸c˜oes poss´ıveis s˜ao:

• Desenvolvimento de uma aplica¸c˜ao que distribua o processamento dos ataques

entre v´arios computadores, tanto para processamento dedicado e n˜ao dedicado.

(45)

Referˆ

encias Bibliogr´

aficas

[1] WIKIPEDIA. Advanced Encryption Standard. July 2005. Dispon´ıvel em:

<http://en.wikipedia.org/wiki/AES>.

[2] STALLINGS, W. Cryptography and Network Security - Principles and Pratice. [S.l.]: Alan Apt, 2003.

[3] NIST. AES Implementation. Dispon´ıvel em:

<http://csrc.nist.gov/encryption/aes/rijndael/rijndael-unix-refc.tar>.

[4] RIJMEN, J. D. V. The Disign of Rijndael. [S.l.]: Springer-Verlag, 2002. [5] RIJNMEN, J. D. V. Aes proposal: Rijndael. 1999.

[6] BARRETO, P. O ataque quadrado. Dispon´ıvel em:

<http://planeta.terra.com.br/informatica/paulobarreto/quadrado.pdf>.

[7] LUCKS, S. Attacking seven rounds of rijndael under 192-bit and 256-bit keys.

AES Candidate Conference 2000, p. 215–229, 2000.

(46)

Apˆ

endice A

odigo Fonte

1Order4Rounds.cpp

#include <cstdio> #include <cstdlib> #include "RijndaelAPI.h" #include "RijndaelAlg.h" #include "conf.h"

extern void inverteChave(RijndaelAlg* rijndaelAlg,BYTE subChave[4][8] ,BYTE chaveMestra[4][KEY_LENGTH/32]); extern void geraConjuntoIntegral(BYTE conjunto[][BLOCK_LENGTH/8]

,unsigned int valorBytesNSaturados); extern void calculaBalanco(BYTE conjunto[256][BLOCK_LENGTH/8]

,BYTE balanco[BLOCK_LENGTH/8]); extern bool balancoCorreto(BYTE bytes[256]);

int main(int argc,char* argv[]){ bool debug = true;

RijndaelAlg* rijndaelAlg; RijndaelAPI* rijndaelAPI;

unsigned int i,j,x,t; //vari´aveis usadas para loops

//necess´ario dois chars para representar um byte em hexadecimal char masterKey[KEY_LENGTH/4] = {’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,

’8’,’9’,’A’,’B’,’C’,’D’,’E’,’F’, ’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’, ’8’,’9’,’A’,’B’,’C’,’D’,’E’,’F’}; //Constroi conjunto integral

(47)

rijndaelAlg = new RijndaelAlg(userInterface,debug);

rijndaelAPI = new RijndaelAPI(rijndaelAlg,userInterface,debug); rijndaelAPI->inicializa(DIR_ENCRYPT,MODE_ECB,NULL,masterKey);

//cifrando

for(i = 0;i < 256;i++){

rijndaelAPI->cifraBloco(conjuntoIntegral1[i],conjuntoIntegralCifrado1[i]); }

for(i = 0;i < 256;i++){

rijndaelAPI->cifraBloco(conjuntoIntegral2[i],conjuntoIntegralCifrado2[i]); } BYTE b1[256][4][8]; BYTE b2[256][4][8]; BYTE subKey5[4][8]; for (x = 0; x < 256; x++){ for (j = 0; j < 4; j++){ for(i = 0; i < 4; i++){

b1[x][i][j] = conjuntoIntegralCifrado1[x][4*j+i] & 0xFF; b2[x][i][j] = conjuntoIntegralCifrado2[x][4*j+i] & 0xFF; } } } for (x = 0; x < 256; x++){ rijndaelAlg->ShiftRow(b1[x],1,4); rijndaelAlg->ShiftRow(b2[x],1,4); } BYTE blockXORkey1; BYTE r1[256]; BYTE blockXORkey2; BYTE r2[256]; bool naoAchouChave; for (j = 0; j < 4; j++){ for(i = 0; i < 4; i++){ subKey5[i][j] = 0; naoAchouChave = true; while(naoAchouChave){ for(t = 0;t < 256;t++){

blockXORkey1 = b1[t][i][j] ^ subKey5[i][j]; blockXORkey2 = b2[t][i][j] ^ subKey5[i][j]; r1[t] = rijndaelAlg->inverseSBox(blockXORkey1); r2[t] = rijndaelAlg->inverseSBox(blockXORkey2); }

if(balancoCorreto(r1) && balancoCorreto(r2))naoAchouChave = false; else subKey5[i][j]++;

(48)

44

rijndaelAlg->ShiftRow(subKey5,0,4);

BYTE chaveMestra[4][KEY_LENGTH/32];

inverteChave(rijndaelAlg,subKey5,chaveMestra); printf("Chave mestra encontrada: ");

for(j = 0; j < KEY_LENGTH/32;j++){ for(i = 0; i < 4; i++){ printf("%X,",chaveMestra[i][j]); } } delete rijndaelAlg; delete rijndaelAPI; delete userInterface; }

RijndaelAPI.h

#ifndef _RIJNDAELAPI_H_ #define _RIJNDAELAPI_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "RijndaelAlg.h" #include "UserInterface.h" /* Defines:

Add any additional defines you need */

#define DIR_ENCRYPT 0 /* Are we encrpyting? */ #define DIR_DECRYPT 1 /* Are we decrpyting? */

#define MODE_ECB 1 /* Are we ciphering in ECB mode? */ #define MODE_CBC 2 /* Are we ciphering in CBC mode? */ #define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ #define TRUE 1

#define FALSE 0

#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */

/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */ #define BAD_KEY_DIR -1 /* Key direction is invalid, e.g.,

unknown value */

#define BAD_KEY_MAT -2 /* Key material not of correct length */

#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ #define BAD_CIPHER_MODE -4 /* Params struct passed to

cipherInit invalid */

#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */

(49)

/* CHANGE POSSIBLE: inclusion of algorithm specific defines */ #define MAX_KEY_SIZE 64 /* # of ASCII char’s needed to

represent a key */

#define MAX_IV_SIZE BITSPERBLOCK/8 /* # bytes needed to represent an IV */

/* Typedefs:

Typedef’ed data storage elements. Add any algorithm specific parameters at the bottom of the structs as appropriate.

*/

//typedef unsigned char BYTE;

/* The structure for key information */ typedef struct {

BYTE direction; /* Key used for encrypting or decrypting? */ int keyLen; /* Length of the key */

char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */ /* The following parameters are algorithm dependent, replace or

add as necessary */

int blockLen; /* block length */

word8 keySched[MAXROUNDS+1][4][MAXBC]; /* key schedule */ }keyInstance;

/* The structure for cipher information */ typedef struct {

BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ BYTE IV[MAX_IV_SIZE]; /* A possible Initialization Vector for

ciphering */

/* Add any algorithm specific parameters needed here */

int blockLen; /* Sample: Handles non-128 bit block sizes (if available) */

} cipherInstance; /* Function protoypes */

/* CHANGED: makeKey(): parameter blockLen added

this parameter is absolutely necessary if you want to setup the round keys in a variable block length setting cipherInit(): parameter blockLen added (for obvious reasons) */

class RijndaelAPI {

public:

(50)

46

int inicializa(int direcao,int modo,char *IV,char chave[KEY_LENGTH/8]); int cifraBloco(BYTE *entrada, BYTE *saida);

int decifraBloco(BYTE *entrada, BYTE *saida);

int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer);

int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer);

int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int Rounds); private: keyInstance keyInst; cipherInstance cipherInst; RijndaelAlg* rijndaelAlg; UserInterface* userInterface; bool debug;

int makeKey(keyInstance *key, BYTE direction,int keyLen,char *keyMaterial); int cipherInit(cipherInstance *cipher, BYTE mode, char *IV);

};

#endif //_RIJNDAELAPI_H_

RijndaelAPI.cpp

#include "RijndaelAPI.h"

//---RijndaelAPI::RijndaelAPI(RijndaelAlg* newRijndaelAlg,UserInterface* newUserInterface ,bool newDebug) { rijndaelAlg = newRijndaelAlg; userInterface = newUserInterface; debug = newDebug; } //---RijndaelAPI::~RijndaelAPI() { } //---int RijndaelAPI::inicializa(//---int direcao,//---int modo,char *IV,char chave[KEY_LENGTH/8]) {

keyInst.blockLen = BLOCK_LENGTH;

makeKey(&keyInst, direcao, KEY_LENGTH, chave); cipherInst.blockLen = BLOCK_LENGTH;

cipherInit(&cipherInst, modo, IV); return 0;

}

(51)

//---int RijndaelAPI::cifraBloco(BYTE *entrada, BYTE *saida) { cipherUpdateRounds(&cipherInst,&keyInst,entrada,BLOCK_LENGTH,saida,ROUND_NUMBER); return 0; } //---int RijndaelAPI::decifraBloco(BYTE *entrada, BYTE *saida)

{

cipherUpdateRounds(&cipherInst, &keyInst,entrada,BLOCK_LENGTH,saida,ROUND_NUMBER); return 0;

}

//---int RijndaelAPI::makeKey(keyInstance *key,BYTE direction,//---int keyLen,char *keyMaterial) { word8 k[4][MAXKC]; int i, j, t; if (key == NULL) { return BAD_KEY_INSTANCE; }

if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { key->direction = direction;

} else {

return BAD_KEY_DIR; }

if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { key->keyLen = keyLen;

} else {

return BAD_KEY_MAT; }

if ( keyMaterial ) {

strncpy(key->keyMaterial, keyMaterial, keyLen/4); }

/* initialize key schedule: */

for(i = 0; i < key->keyLen/8; i++) { t = key->keyMaterial[2*i];

if ((t >= ’0’) && (t <= ’9’)) j = (t - ’0’) << 4;

else if ((t >= ’a’) && (t <= ’f’)) j = (t - ’a’ + 10) << 4; else if ((t >= ’A’) && (t <= ’F’)) j = (t - ’A’ + 10) << 4; else return BAD_KEY_MAT;

t = key->keyMaterial[2*i+1];

if ((t >= ’0’) && (t <= ’9’)) j ^= (t - ’0’);

(52)

48

k[i % 4][i / 4] = (word8) j; } printf("Chave usada:"); for(j = 0; j < KEY_LENGTH/32;j++){ for(i = 0; i < 4; i++){ printf("%X,",k[i][j]); } } printf("\n");

rijndaelAlg->rijndaelKeySched (k, key->keyLen, key->blockLen, key->keySched); return TRUE;

}

//---int RijndaelAPI::cipherInit(cipherInstance *cipher, BYTE mode, char *IV)

{

int i, j, t;

if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { cipher->mode = mode;

} else {

return BAD_CIPHER_MODE; }

if (IV != NULL) {

for(i = 0; i < cipher->blockLen/8; i++) { t = IV[2*i];

if ((t >= ’0’) && (t <= ’9’)) j = (t - ’0’) << 4;

else if ((t >= ’a’) && (t <= ’f’)) j = (t - ’a’ + 10) << 4; else if ((t >= ’A’) && (t <= ’F’)) j = (t - ’A’ + 10) << 4; else return BAD_CIPHER_INSTANCE;

t = IV[2*i+1];

if ((t >= ’0’) && (t <= ’9’)) j ^= (t - ’0’);

else if ((t >= ’a’) && (t <= ’f’)) j ^= (t - ’a’ + 10); else if ((t >= ’A’) && (t <= ’F’)) j ^= (t - ’A’ + 10); else return BAD_CIPHER_INSTANCE;

cipher->IV[i] = (BYTE) j; } } return TRUE; } //---int RijndaelAPI::blockEncrypt(cipherInstance *cipher,

keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer) {

(53)

/* check parameter consistency: */ if (key == NULL ||

key->direction != DIR_ENCRYPT ||

(key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256)){ return BAD_KEY_MAT;

}

if (cipher == NULL ||

(cipher->mode != MODE_ECB && cipher->mode != MODE_CBC && cipher->mode != MODE_CFB1) ||

(cipher->blockLen != 128 && cipher->blockLen != 192 && cipher->blockLen != 256)) { return BAD_CIPHER_STATE; } numBlocks = inputLen/cipher->blockLen; switch (cipher->mode) { case MODE_ECB:

for (i = 0; i < numBlocks; i++) {

for (j = 0; j < cipher->blockLen/32; j++) { for(t = 0; t < 4; t++)

/* parse input stream into rectangular array */ block[t][j] = input[4*j+t] & 0xFF;

}

rijndaelAlg->rijndaelEncrypt (block, key->keyLen, cipher->blockLen, key->keySched); for (j = 0; j < cipher->blockLen/32; j++) {

/* parse rectangular array into output ciphertext bytes */ for(t = 0; t < 4; t++)

outBuffer[4*j+t] = (BYTE) block[t][j]; } } break; case MODE_CBC: for (j = 0; j < cipher->blockLen/32; j++) { for(t = 0; t < 4; t++)

/* parse initial value into rectangular array */ block[t][j] = cipher->IV[t+4*j] & 0xFF; }

for (i = 0; i < numBlocks; i++) {

for (j = 0; j < cipher->blockLen/32; j++) { for(t = 0; t < 4; t++)

/* parse input stream into rectangular array and exor with IV or the previous ciphertext */

block[t][j] ^= input[4*j+t] & 0xFF; }

(54)

50

/* parse rectangular array into output ciphertext bytes */ for(t = 0; t < 4; t++)

outBuffer[4*j+t] = (BYTE) block[t][j]; }

} break;

default: return BAD_CIPHER_STATE; }

return numBlocks*cipher->blockLen; }

//---int RijndaelAPI::blockDecrypt(cipherInstance *cipher,

keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer) { int i, j, t, numBlocks; word8 block[4][MAXBC]; if (cipher == NULL || key == NULL || key->direction == DIR_ENCRYPT || cipher->blockLen != key->blockLen) { return BAD_CIPHER_STATE; }

/* check parameter consistency: */ if (key == NULL ||

key->direction != DIR_DECRYPT ||

(key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256)){ return BAD_KEY_MAT;

}

if (cipher == NULL ||

(cipher->mode != MODE_ECB && cipher->mode != MODE_CBC && cipher->mode != MODE_CFB1) ||

(cipher->blockLen != 128 && cipher->blockLen != 192 && cipher->blockLen != 256)) { return BAD_CIPHER_STATE; } numBlocks = inputLen/cipher->blockLen; switch (cipher->mode) { case MODE_ECB:

for (i = 0; i < numBlocks; i++) {

for (j = 0; j < cipher->blockLen/32; j++) { for(t = 0; t < 4; t++)

/* parse input stream into rectangular array */ block[t][j] = input[4*j+t] & 0xFF;

}

(55)

for (j = 0; j < cipher->blockLen/32; j++) {

/* parse rectangular array into output ciphertext bytes */ for(t = 0; t < 4; t++)

outBuffer[4*j+t] = (BYTE) block[t][j]; } } break; case MODE_CBC: /* first block */ for (j = 0; j < cipher->blockLen/32; j++) { for(t = 0; t < 4; t++)

/* parse input stream into rectangular array */ block[t][j] = input[4*j+t] & 0xFF;

}

rijndaelAlg->rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched); for (j = 0; j < cipher->blockLen/32; j++) {

/* exor the IV and parse rectangular array into output ciphertext bytes */ for(t = 0; t < 4; t++)

outBuffer[4*j+t] = (BYTE) (block[t][j] ^ cipher->IV[t+4*j]); }

/* next blocks */

for (i = 1; i < numBlocks; i++) {

for (j = 0; j < cipher->blockLen/32; j++) { for(t = 0; t < 4; t++)

/* parse input stream into rectangular array */

block[t][j] = input[cipher->blockLen/8+4*j+t] & 0xFF; }

rijndaelAlg->rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched); for (j = 0; j < cipher->blockLen/32; j++) {

/* exor previous ciphertext block and parse rectangular array into output ciphertext bytes */

for(t = 0; t < 4; t++)

outBuffer[cipher->blockLen/8+4*j+t] = (BYTE) (block[t][j] ^ input[4*j+t-4*cipher->blockLen/32]);

} } break;

default: return BAD_CIPHER_STATE; }

return numBlocks*cipher->blockLen; }

(56)

52

* cipherUpdateRounds: *

* Encrypts/Decrypts exactly one full block a specified number of rounds. * Only used in the Intermediate Value Known Answer Test.

*

* Returns:

* TRUE - on success

* BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) */

int RijndaelAPI::cipherUpdateRounds(cipherInstance *cipher,

keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds) { int j, t; word8 block[4][MAXBC]; if (cipher == NULL || key == NULL || cipher->blockLen != key->blockLen) { return BAD_CIPHER_STATE; } for (j = 0; j < cipher->blockLen/32; j++) { for(t = 0; t < 4; t++)

/* parse input stream into rectangular array */ block[t][j] = input[4*j+t] & 0xFF;

} switch (key->direction) { case DIR_ENCRYPT: rijndaelAlg->rijndaelEncryptRound(block,key->keyLen,cipher->blockLen, key->keySched, rounds); break; case DIR_DECRYPT: rijndaelAlg->rijndaelDecryptRound(block,key->keyLen,cipher->blockLen, key->keySched, rounds); break;

default: return BAD_KEY_DIR; }

for (j = 0; j < cipher->blockLen/32; j++) {

/* parse rectangular array into output ciphertext bytes */ for(t = 0; t < 4; t++)

outBuffer[4*j+t] = (BYTE) block[t][j]; }

return TRUE; }

RijndaelAlg.h

(57)

#define _RIJNDAELALG_H_

#define MAXBC (256/32) #define MAXKC (256/32) #define MAXROUNDS 14

typedef unsigned char word8; typedef unsigned short word16; typedef unsigned long word32;

#include <stdio.h> #include <stdlib.h> #include "conf.h"

#include "UserInterface.h" #define SC ((BC - 4) >> 1)

static word8 shifts[3][4][2] = { 0, 0, 1, 3, 2, 2, 3, 1, 0, 0, 1, 5, 2, 4, 3, 3, 0, 0, 1, 7, 3, 5, 4, 4 }; class RijndaelAlg { public:

RijndaelAlg(UserInterface* newUserInterface,bool newDebug); ~RijndaelAlg();

word8 sBox(word8 byte);

word8 inverseSBox(word8 byte); word8 roundConstant(int index);

void ShiftRow(word8 a[4][MAXBC], word8 d, word8 BC);

int rijndaelKeySched (word8 k[4][MAXKC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC]);

int rijndaelEncrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC]);

(58)

54

int rijndaelDecrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC]);

int rijndaelDecryptRound (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC], int rounds);

private:

UserInterface* userInterface; bool debug;

word8 mul(word8 a, word8 b);

void KeyAddition(word8 a[4][MAXBC], word8 rk[4][MAXBC], word8 BC); void Substitution(word8 a[4][MAXBC], word8 box[256], word8 BC); void MixColumn(word8 a[4][MAXBC], word8 BC);

void InvMixColumn(word8 a[4][MAXBC], word8 BC);

void copiaBloco(BYTE blocos[ROUND_NUMBER*4+1][4][BLOCK_LENGTH/32]

,BYTE bloco[4][MAXBC],int blcIndex); }; #endif //_RIJNDAELALG_H_

RijndaelAlg.cpp

#include "RijndaelAlg.h" #include "boxes-ref.dat" #include <stdio.h>

RijndaelAlg::RijndaelAlg(UserInterface* newUserInterface,bool newDebug) { userInterface = newUserInterface; debug = newDebug; } //---RijndaelAlg::~RijndaelAlg() { } //---word8 RijndaelAlg::inverseSBox(//---word8 byte)

{

return Si[byte]; }

//---word8 RijndaelAlg::sBox(//---word8 byte)

{

return S[byte]; }

//---word8 RijndaelAlg::roundConstant(int index)

{

return rcon[index]; }

//---word8 RijndaelAlg::mul(//---word8 a, //---word8 b) {

Referências

Documentos relacionados

No caso de um plano ter um fundo de benefícios de reforma constituido, a quantia contribuída por uma entidade para o fundo, durante um período, não é necessariamente igual à

Com relação à germinação das sementes armazenadas em câmara fria, aos três meses de armazenamento (Tabela 10), observou-se em sementes tratadas ou não com fungicidas e

c.4) Não ocorrerá o cancelamento do contrato de seguro cujo prêmio tenha sido pago a vista, mediante financiamento obtido junto a instituições financeiras, no

Para tanto, nossa proposta de trabalho está em pesquisar algumas ações do Museu Histórico de Campos dos Goytacazes (MHCG) e perceber se há ou não intenções de Educação

Conforme a adesão à medicação, para este estudo, considerou-se apenas o consentimento da terapia antirretroviral, visto que a literatura não apresenta nenhum

- Se o estagiário, ou alguém com contacto direto, tiver sintomas sugestivos de infeção respiratória (febre, tosse, expetoração e/ou falta de ar) NÃO DEVE frequentar

A relação da educação geral e a Educação Física precisam está ligadas ao que o ambiente escolar necessita, como também, atender aos parâmetros de inclusão ao aluno que faz-se

Em pacientes usando outras drogas que não induzem ou inibem significativamente a glicuronidação da lamotrigina (ver Interações medicamentosas), a dose inicial de lamotrigina e 25