• Nenhum resultado encontrado

3. Implementação

3.4. Implementação em Hardware Usando DRSS

A implementação de um encriptador usando uma lógica DRSS foi um desafio interessante de abordar, envolvendo uma alteração profunda a nível do funcionamento do demonstrador já desenvolvido.

Como referido atrás a alteração de um circuito usando lógica regular, também chamada de single-rail, para uma lógica dual-rail implica não só a codificação dos dados num barramento duplo por bit, mas também uma alteração a nível da forma como o resultado lógico é calculado, nomeadamente pela necessidade de a codificação ser capaz de conviver com valores inválidos como os introduzidos pelo spacer. Este factor vai trazer consequências a nível da dimensão do componente uma vez que uma simples porta lógica, que faria o cálculo necessário, será substituída por um circuito lógico.

Abordando este problema numa perspectiva bottom-up temos que considerar que portas lógicas são usadas no algoritmo AES e como devemos alterar o circuito para, no seu lugar, existir algo capaz de gerar os resultados correctos para os valores codificados em DRSS.

De uma forma concreta, a porta lógica essencial para a implementação do AES é o XOR. Esta porta é usada durante nas operações de Key Expansion, Add Round Key e Mix Columns, sendo o resto do algoritmo implementado por alterações da posição do byte (Shift Row) e por endereçamento de posições de S-Box através do valor do byte (Sub. Bytes). Durante a fase de Mix Columns é também usado o shift left a nível do bit.

É necessário então converter o XOR em single-rail numa porta dual-rail capaz de corresponder à dita codificação. Para isso é preciso compreender o funcionamento de um XOR, recorrendo-se então à tabela de verdade de um XOR.

Tabela 11 - Tabela de verdade de um XOR

A

B

Out

A B Out 0 0 0 0 1 1 1 0 1 1 1 0

58

Com a ajuda da Tabela 11 podemos então gerar a tabela de verdade equivalente para o XOR em codificação DRSS, que corresponde à Tabela 12. Como estamos a considerar uma implementação DRSS e o spacer seleccionado foi o zero spacer, considera-se impossível ocorrer uma situação em que ambos os valores de cada barramento possuam valor 1. Como existem valores válidos e inválidos é necessário incluir uma parte do circuito que permita a detecção destes.

Tabela 12 - Tabela de verdade de um XOR DRSS

A0 A1 B0 B1 Out0 Out1 Enable

0 0 x x 0 0 0 x x 0 0 0 0 0 0 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 0 1 1 0 1 1 0 1 0 0 1 1

Um circuito lógico, que permite uma aproximação a esta tabela de verdade, pode ser desenhado da forma que vemos na Imagem 36. No entanto este não garante a constante validade das palavras colocadas na sua saída, ou seja, se apenas uma entrada for válida, o barramento Out pode ter uma palavra de dados, sendo necessário gerir o Enable na lógica externa à porta. Não garante portanto a correspondência total à tabela de verdade desejada.

A1 A1 A0 B1 B0 Out1 Out2 Enable

59 Para garantir a correspondência total à tabela de verdade o sinal de Enable deve ser usado para controlar directamente a saída garantindo assim a validade da palavra à saída do circuito lógico. Com esse intuito obteve-se o circuito lógico representado na Imagem 37.

A1 A1 A0 B1 B0 Out1 Out2 Enable

Imagem 37 - XOR DRSS válido com sinal de Enable

A execução deste circuito em Verilog pode ser descrita da forma visível na Imagem 38, permitindo assim a aplicação do DRSS ao AES.

Imagem 38 - Código Verilog de um XOR DRSS

Com a sintetização desta descrição obtemos a esquemática RTL que podemos ver na Imagem 39. module xor_drss( input [1:0] a, input [1:0] b, output[1:0] c );

assign c[1] = ((a[1]^a[0]) && (b[1]^b[0]))? (a[1]&!a[0]) ^ (b[1]&!b[0]): 0;

assign c[0] = ((a[1]^a[0]) && (b[1]^b[0]))? !((a[1]&a[0])^ (b[1]&!b[0])) : 0;

60

Imagem 39 - Esquemática RTL de XOR DRSS

Como acima referido, outra das operações necessárias para realizar a encriptação AES é a realização de um shift left a nível do bit durante a realização da operação Mix Columns. Portanto é também necessário abordar a transição desta operação para DRSS.

Com o conceito de DRSS um byte, ou seja 8 bits, passou a ter o seu valor codificado em 16 bits e, como tal, é necessário adaptar o shift left a isso. É também necessário considerar que o valor binário ‘0’ passou a ser codificado por ‘01’ e, desse modo, para completar o byte, quando este vê o seu valor rodado para a esquerda, é necessário concatenar esse valor ao mesmo. O código que realiza essa tarefa pode ser visto na Imagem 40.

Imagem 40 - Código Verilog ShiftLeft DRSS

Com estes dois componentes convertidos para DRSS é necessário agora considerar a conversão das S-Box.

module shift_left_byte_drss( input [15:0] a, output[15:0] b ); assign b = {a[13:0],2'b01; endmodule

61 As S-Box são, como já explicado, uma parte essencial do algoritmo AES, sendo usadas para realizar uma substituição não linear no campo finito de Galois GF(28), como tal faz todo o sentido converter a codificação desta tabela a nível de código ao invés de a converter durante o processo de encriptação, tanto do ponto de vista throughput como do ponto de vista do espaço ocupado.

No ponto 1.2.3, na Tabela 1, é possível ver uma S-Box gerada para uma implementação sem contramedida. Para converter essa implementação numa implementação válida para DRSS é necessário, então, modificar cada um dos seus conteúdos de 8 para 16 bits segundo a codificação já descrita. Para esse efeito foi desenvolvida uma pequena aplicação em C# para automatizar a conversão dos valores.

Esta aplicação toma como input um ficheiro de texto com uma S-Box no formato visível na Imagem 41, onde também se pode ver imagens do seu funcionamento.

Imagem 41 - Funcionamento do conversor S-Box SR/DRSS

Após a execução devolve já o código Verilog necessário para implementar a S-Box, como se pode ver pela parte do ficheiro presente na Imagem 42.

62

Imagem 42 - Excerto do código da S-Box DRSS gerado pelo conversor

Não abandonando a operação Sub. Byte é necessário que esta seja capaz de receber os dados codificados e de realizar as substituições numa S-Box com as mesmas dimensões que a original. Para isso é necessário recorrer a uma forma de descodificar os dados durante o endereçamento sem que isso afecte a eficiência das contramedidas implementadas.

De maneira a realizar esta tarefa é necessário descodificar o conteúdo dos bits para endereçar a linha, como se pode ver na Imagem 43.

assign sbox[0] = { 16'h6659, 16'h5596, 16'h6999, 16'ha666, 16'h5a55, 16'h5a69, 16'h9966, 16'h5a95, 16'h9aaa, 16'h6555, 16'h995a, 16'h96a9, 16'h9556, 16'haa5a, 16'ha66a, 16'haa9a };

assign sbox[1] = { 16'h6aa5, 16'ha95a, 16'h5a96, 16'h9559, 16'h969a, 16'h59aa, 16'haaaa, 16'h956a, 16'h5a65, 16'h95a9, 16'h655a, 16'h6565, 16'ha565, 16'ha6a9, 16'ha996, 16'ha59a };

assign sbox[2] = { 16'h6665, 16'h6a9a, 16'h9665, 16'h5a59, 16'h9969, 16'ha559, 16'h595a, 16'h5aa6, 16'ha9a9, 16'h65a5, 16'h9666, 16'h559a, 16'h6559, 16'haa99, 16'ha55a, 16'h65a9 };

assign sbox[3] = { 16'h5595, 16'h59a9, 16'h9956, 16'h6969, 16'h5995, 16'ha696, 16'h5965, 16'h9a59, 16'h6a69, 16'h669a, 16'h9959, 16'h6596, 16'h69a6, 16'h959a, 16'ha656, 16'h5966 };

assign sbox[4] = { 16'h6a59, 16'haa95, 16'haa69, 16'h6965, 16'h9569, 16'h6995, 16'h9695, 16'h5669, 16'ha665, 16'h9965, 16'h66a5, 16'ha5a5, 16'h66a6, 16'h6966, 16'h9a69, 16'h9659 };

assign sbox[5] = { 16'h69a5, 16'h6a55, 16'h6595, 16'h6655, 16'haaa6, 16'ha9a6, 16'h9a96, 16'ha699, 16'h66a9, 16'h5666, 16'h6569, 16'h666a, 16'h996a, 16'h95a6, 16'h96a6, 16'h9565 };

assign sbox[6] = { 16'h9655, 16'ha695, 16'h999a, 16'h5555, 16'h95a5, 16'h9aa5, 16'ha65a, 16'h5599, 16'haa6a, 16'ha965, 16'h6695, 16'h5566, 16'h9a95, 16'h9a5a, 16'h6566, 16'h5569 };

assign sbox[7] = { 16'ha655, 16'h59a5, 16'h56a9, 16'h95aa, 16'ha599, 16'h5aaa, 16'h55aa, 16'h5559, 16'ha556, 16'h99aa, 16'h9aa6, 16'h555a, 16'h5556, 16'h565a, 16'h9599, 16'h699a };

assign sbox[8] = { 16'h5a99, 16'h9656, 16'h5656, 16'h6556, 16'h65aa, 16'h696a, 16'ha6a5, 16'ha999, 16'h966a, 16'haa59, 16'ha5aa, 16'ha5a9, 16'haa55, 16'h9a65, 16'ha969, 16'h6a5a };

assign sbox[9] = { 16'h9669, 16'h99a5, 16'h6a65, 16'h5959, 16'ha96a, 16'h99a6, 16'h5a66, 16'h9566, 16'ha959, 16'haa96, 16'h5a6a, 16'ha995, 16'h56a5, 16'h6a66, 16'ha6aa, 16'h69a9 };

63

Imagem 43 - Sub. Bytes DRSS (linhas)

E descodificar a coluna em que está os valores que vão substituir os bytes, podemos ver esse código na Imagem 44.

Imagem 44 - Sub. Bytes DRSS (colunas) module l_dec(

input [7:0]linha,

output [3:0]l );

assign l = (linha == 8'hAA)? 15: (linha == 8'hA9)? 14: (linha == 8'hA6)? 13: (linha == 8'hA5)? 12: (linha == 8'h9A)? 11: (linha == 8'h99)? 10: (linha == 8'h96 )? 9: (linha == 8'h95 )? 8: (linha == 8'h6A )? 7: (linha == 8'h69 )? 6: (linha == 8'h66 )? 5: (linha == 8'h65 )? 4: (linha == 8'h5A )? 3: (linha == 8'h59 )? 2: (linha == 8'h56 )? 1: 0; endmodule module c_dec( input [255:0] sbox_linha, input [7:0]coluna, output [15:0]valor ); assign valor =

(coluna == 8'hAA )? sbox_linha[15 :0 ]: (coluna == 8'hA9 )? sbox_linha[31 :16 ]: (coluna == 8'hA6 )? sbox_linha[47 :32 ]: (coluna == 8'hA5 )? sbox_linha[63 :48 ]: (coluna == 8'h9A )? sbox_linha[79 :64 ]: (coluna == 8'h99 )? sbox_linha[95 :80 ]: (coluna == 8'h96 )? sbox_linha[111:96 ]: (coluna == 8'h95 )? sbox_linha[127:112]: (coluna == 8'h6A )? sbox_linha[143:128]: (coluna == 8'h69 )? sbox_linha[159:144]: (coluna == 8'h66 )? sbox_linha[175:160]: (coluna == 8'h65 )? sbox_linha[191:176]: (coluna == 8'h5A )? sbox_linha[207:192]: (coluna == 8'h59 )? sbox_linha[223:208]: (coluna == 8'h56 )? sbox_linha[239:224]: sbox_linha[255:240];

64

É essencial também para a aplicação do DRSS converter o próprio plaintext de single-rail para a codificação dual-rail, bem como na direcção inversa, permitindo uma utilização transparente deste método. Como tal foi necessário implementar um conjunto de módulos que permitissem a realização dessa tarefa.

Com recurso a uma pequena máquina de estados implementou-se a conversão entre single-rail e dual-rail, tornando, deste modo, garantida a obrigatoriedade da passagem pelo estado de spacer, Na Imagem 45 pode-se visualizar parte da esquemática correspondente a esta mesma máquina de estados.

Imagem 45 - Esquemática e topblock do conversor de SR para DRSS

O conversor na direcção contrária, ou seja dual para single-rail foi implementado também, de modo semelhante. Pode-se ver parcialmente a esquemática na Imagem 46.

Imagem 46 – Esquemática e topblock de conversor DRSS para SR

Com a conjugação de todos os factores nomeados até este momento neste ponto é possível proceder à alteração da implementação sem contramedidas de modo a incluir esta técnica.

65 A implementação desta técnica implicou um overhead bastante grande em termos de espaço ocupado na FPGA, sendo esse mesmo factor uma das maiores desvantagens da sua aplicação.