FACULDADE DE TECNOLOGIA UNIVERSIDADE DE BRASÍLIA



Documentos relacionados
PARALELIZAÇÃO DE APLICAÇÕES NA ARQUITETURA CUDA: UM ESTUDO SOBRE VETORES 1

Sistema de Computação

Introdução. Introdução. Introdução. Organização Estruturada de Computadores. Introdução. Máquinas Multiníveis

Informática I. Aula 5. Aula 5-13/05/2006 1

Arquitetura e Organização de Computadores. Capítulo 0 - Introdução

Organização e Arquitetura de Computadores I. de Computadores

Arquitetura e Organização de Computadores. Capítulo 0 - Introdução

Sistemas Operacionais

Hardware (Nível 0) Organização. Interface de Máquina (IM) Interface Interna de Microprogramação (IIMP)

3. O NIVEL DA LINGUAGEM DE MONTAGEM

ARQUITETURA DE COMPUTADORES

AULA4: PROCESSADORES. Figura 1 Processadores Intel e AMD.

Organização e Arquitetura de Computadores I. de Computadores

Processos e Threads (partes I e II)

ESTUDO DE CASO WINDOWS VISTA

FACULDADE PITÁGORAS DISCIPLINA: ARQUITETURA DE COMPUTADORES

7 Processamento Paralelo

Segurança de Redes de Computadores. Ricardo José Cabeça de Souza

Sistemas Operacionais

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

Capítulo 1 Introdução

Arquiteturas RISC. (Reduced Instructions Set Computers)

AULA 1. Informática Básica. Gustavo Leitão. Disciplina: Professor:

NOTAS DE AULA Prof. Antonio Carlos Schneider Beck Filho (UFSM) Prof. Júlio Carlos Balzano de Mattos (UFPel) Arquitetura de Von Neumann

7.Conclusão e Trabalhos Futuros

BARRAMENTO DO SISTEMA

1.1. Organização de um Sistema Computacional

Figura 1 - O computador

Placa de vídeo em CUDA

Capacidade = 512 x 300 x x 2 x 5 = ,72 GB

Tais operações podem utilizar um (operações unárias) ou dois (operações binárias) valores.

Capítulo 8 Arquitetura de Computadores Paralelos

O hardware é a parte física do computador, como o processador, memória, placamãe, entre outras. Figura 2.1 Sistema Computacional Hardware

Dadas a base e a altura de um triangulo, determinar sua área.

Máquinas Multiníveis

TRABALHO COM GRANDES MONTAGENS

CPU Unidade Central de Processamento. História e progresso

ORGANIZAÇÃO DE COMPUTADORES MÓDULO 8

O processador é composto por: Unidade de controlo - Interpreta as instruções armazenadas; - Dá comandos a todos os elementos do sistema.

Arquitetura de Computadores - Arquitetura RISC. por Helcio Wagner da Silva

INTRODUÇÃO À PROGRAMAÇÃO BCC 201 TURMAS 31, 32 E AULA TEÓRICA 2 PROF. MARCELO LUIZ SILVA (R E D)

Introdução aos Computadores

Capítulo 4. MARIE (Machine Architecture Really Intuitive and Easy)

Sistemas Distribuídos

Edeyson Andrade Gomes

Guilherme Pina Cardim. Relatório de Sistemas Operacionais I

Introdução a Informática. Prof.: Roberto Franciscatto

Tecnologia PCI express. Introdução. Tecnologia PCI Express

Memória Cache. Prof. Leonardo Barreto Campos 1


Ao longo do presente capítulo será apresentada uma descrição introdutória da tecnologia FPGA e dos módulos básicos que a constitui.

for Information Interchange.

IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira

Sistemas Operacionais Processos e Threads

Introdução à Organização e Arquitetura de Computadores. Prof. Leonardo Barreto Campos 1

Tabela de Símbolos. Análise Semântica A Tabela de Símbolos. Principais Operações. Estrutura da Tabela de Símbolos. Declarações 11/6/2008

Capítulo 3. Avaliação de Desempenho. 3.1 Definição de Desempenho

Notas da Aula 15 - Fundamentos de Sistemas Operacionais

Esta dissertação apresentou duas abordagens para integração entre a linguagem Lua e o Common Language Runtime. O objetivo principal da integração foi

Paralelismo. Computadores de alto-desempenho são utilizados em diversas áreas:

BACHARELADO EM SISTEMAS DE INFORMAÇÃO EaD UAB/UFSCar Sistemas de Informação - prof. Dr. Hélio Crestana Guardia

Imagem retirada de documentações de treinamentos oficiais INTEL

Memórias Prof. Galvez Gonçalves

UNIVERSIDADE FEDERAL DE SANTA CATARINA UFSC DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA INE BACHARELADO EM CIÊNCIAS DA COMPUTAÇÃO.

Diminui o gargalo existente entre processador e memória principal; 5 a 10 vezes mais rápidas que a memória principal; Ligada diretamente à MP;

BRAlarmExpert. Software para Gerenciamento de Alarmes. BENEFÍCIOS obtidos com a utilização do BRAlarmExpert:

Hardware de Computadores

Organização de Computadores Hardware

Sistemas Computacionais II Professor Frederico Sauer

Arquitetura dos Sistemas de Informação Distribuídos

CAPÍTULO 7 NÍVEL DE LINGUAGEM DE MONTAGEM

3/9/2010. Ligação da UCP com o barramento do. sistema. As funções básicas dos registradores nos permitem classificá-los em duas categorias:

Curso: Técnico de Informática Disciplina: Redes de Computadores. 1- Apresentação Binária

PROJETO LÓGICO DE COMPUTADORES Prof. Ricardo Rodrigues Barcelar

Organização de Computadores

Bits internos e bits externos. Barramentos. Processadores Atuais. Conceitos Básicos Microprocessadores. Sumário. Introdução.

Computador E/S, Memória, Barramento do sistema e CPU Onde a CPU Registradores, ULA, Interconexão interna da CPU e Unidade de controle.

Histórico da Revisão. Versão Descrição Autor. 1.0 Versão Inicial

Visão geral do sistema de armazenamento e hierarquia de memória

Introdução à Arquitetura de Computadores. Renan Manola Introdução ao Computador 2010/01

Desenvolvendo uma Arquitetura de Componentes Orientada a Serviço SCA

Intranets. FERNANDO ALBUQUERQUE Departamento de Ciência da Computação Universidade de Brasília 1.INTRODUÇÃO

Veja abaixo um exemplo de um endereço IP de 32 bits:

Introdução. INF1005 Programação I 33K Prof. Gustavo Moreira gmoreira@inf.puc-rio.br

Curso de Instalação e Gestão de Redes Informáticas

Universidade Federal de Santa Maria Curso de Arquivologia. Disciplina de Banco de Dados Aplicados à Arquivística. Versao 1.

VIRTUALIZAÇÃO CONVENCIONAL

5 Mecanismo de seleção de componentes

Arquitetura de Computadores Paralelismo, CISC X RISC, Interpretação X Tradução, Caminho de dados

Cálculo Aproximado do número PI utilizando Programação Paralela

Notas da Aula 17 - Fundamentos de Sistemas Operacionais

1. CAPÍTULO COMPUTADORES

4 Estrutura do Sistema Operacional Kernel

Fundamentos de Sistemas de Informação Hardware: Dispositivos de Entrada, Processamento e Saída

ULA Sinais de Controle enviados pela UC

Orientação a Objetos

Análises Geração RI (representação intermediária) Código Intermediário

Sistemas Operacionais. Prof. André Y. Kusumoto

Arquitetura de Computadores RISC x CISC. Gustavo Pinto Vilar

Transcrição:

IMPLEMENTAÇÃO DO AES NA PLATAFORMA CUDA MARCEL AUGUSTUS BARBOSA CARVALHO DISSERTAÇÃO DE MESTRADO EM ENGENHARIA ELÉTRICA DEPARTAMENTO DE ENGENHARIA ELÉTRICA FACULDADE DE TECNOLOGIA UNIVERSIDADE DE BRASÍLIA

UNIVERSIDADE DE BRASÍLIA FACULDADE DE TECNOLOGIA DEPARTAMENTO DE ENGENHARIA ELÉTRICA IMPLEMENTAÇÃO DO AES NA PLATAFORMA CUDA MARCEL AUGUSTUS BARBOSA CARVALHO ORIENTADOR: ANDERSON CLAYTON ALVES NASCIMENTO DISSERTAÇÃO DE MESTRADO EM ENGENHARIA ELÉTRICA PUBLICAÇÃO: PPGENE.DM - 490 A/12 BRASÍLIA/DF: SETEMBRO - 2012.

UNIVERSIDADE DE BRASÍLIA FACULDADE DE TECNOLOGIA DEPARTAMENTO DE ENGENHARIA ELÉTRICA IMPLEMENTAÇÃO DO AES NA PLATAFORMA CUDA MARCEL AUGUSTUS BARBOSA CARVALHO DISSERTAÇÃO DE MESTRADO SUBMETIDA AO DEPARTAMENTO DE ENGE- NHARIA ELÉTRICA DA FACULDADE DE TECNOLOGIA DA UNIVERSIDADE DE BRASÍLIA, COMO PARTE DOS REQUISITOS NECESSÁRIOS PARA A OB- TENÇÃO DO GRAU DE MESTRE EM ENGENHARIA ELÉTRICA. APROVADA POR: Prof. Dr. Anderson Clayton Alves Nascimento (ENE-UnB) (Orientador) Prof. Dr. Rafael Timóteo de Sousa Jr. (ENE-UnB) (Examinador Interno) Prof. Dr. Diego de Freitas Aranha (CIC-UnB) (Examinador Externo) BRASÍLIA/DF, 17 DE SETEMBRO DE 2012. ii

FICHA CATALOGRÁFICA CARVALHO, MARCEL AUGUSTUS BARBOSA Implementação do AES na Plataforma CUDA. [Distrito Federal] 2012. xvii, 144p., 297 mm (ENE/FT/UnB, Mestre, Engenharia Elétrica, 2012). Dissertação de Mestrado - Universidade de Brasília. Faculdade de Tecnologia. Departamento de Engenharia Elétrica. 1. Criptograa 2. AES 3. GPGPU 4. CUDA I. ENE/FT/UnB II. Título (série) REFERÊNCIA BIBLIOGRÁFICA CARVALHO, M. A. B. (2012). Implementação do AES na plataforma CUDA. Dissertação de Mestrado em Engenharia Elétrica, Publicação PPGENE.DM - 490 A/12, Departamento de Engenharia Elétrica, Universidade de Brasília, Brasília, DF, 144p. CESSÃO DE DIREITOS NOME DO AUTOR: Marcel Augustus Barbosa Carvalho. TÍTULO DA DISSERTAÇÃO DE MESTRADO: Implementação do AES na plataforma CUDA GRAU / ANO: Mestre / 2012 É concedida à Universidade de Brasília permissão para reproduzir cópias desta dissertação de mestrado e para emprestar ou vender tais cópias somente para propósitos acadêmicos e cientícos. O autor reserva outros direitos de publicação e nenhuma parte desta dissertação de mestrado pode ser reproduzida sem a autorização por escrito do autor. Marcel Augustus Barbosa Carvalho Universidade de Brasília - Faculdade de Tecnologia Departamento de Engenharia Elétrica 70910-900 Brasília-DF Brasil. iii

AGRADECIMENTOS Agradeço à Professora Doutora Alba Cristina Magalhães Alves de Melo por gentilmente ceder as instalações do Laboratório de Sistemas Integrados e Concorrentes (LAICO) do Departamento de Ciência da Computação da Universidade de Brasília, para a mensuração dos resultados descritos nesta dissertação em hardwares de ponta. Agradeço também ao Chefe do Centro de Desenvolvimento de Sistemas do Exército Brasileiro, General de Brigada Bráulio de Paula Machado, pelo total apoio e forte incentivo para a nalização deste trabalho. MARCEL AUGUSTUS BARBOSA CARVALHO iv

Dedicatória Dedico este trabalho a minha amada esposa Jaqueline Lima e minhas lindas lhas Camille Pietra e Nicole Jolie que tanto me apoiaram nesse árduo caminho mesmo em detrimento da minha constante ausência do convívio familiar. MARCEL AUGUSTUS BARBOSA CARVALHO v

RESUMO IMPLEMENTAÇÃO DO AES NA PLATAFORMA CUDA Autor: Marcel Augustus Barbosa Carvalho Orientador: Anderson Clayton Alves Nascimento Programa de Pós-graduação em Engenharia Elétrica Brasília, setembro de 2012 Compute Unied Device Architecture (CUDA) é uma plataforma de computação paralela de propósito geral que tira proveito das unidades de processamento gráco (GPU) NVIDIA para resolver problemas computacionais que possam ser paralelizáveis. No campo da criptograa já foram realizados esforços no uso de GPUs com algoritmos criptográcos simétricos e assimétricos e mais recentemente com as funções de hash. Este trabalho realiza uma revisão das implementações anteriores do AES sobre GPUs e implementa o algoritmo AES para cifração e decifração com chaves de 128, 192 e 256 bits no modo ECB com padding, com variações no uso dos recursos disponíveis nas GPUs CUDA. Como resultado nal chegou-se a implementação em CUDA cuja conguração de recursos levou a ganhos no tempo total de cifração/decifração de até 32,7 vezes comparados à versão em CPU usada como referência. vi

ABSTRACT IMPLEMENTATION OF AES ON THE CUDA PLATAFORM Author: Marcel Augustus Barbosa Carvalho Supervisor: Anderson Clayton Alves Nascimento Programa de Pós-graduação em Engenharia Elétrica Brasília, september of 2012 Compute Unied Device Architecture (CUDA) is a platform for general purpose parallel computing that takes advantage of NVIDIA Graphic Processing Units (GPU) to solve parallelizable computational problems. In the eld of the cryptography eorts have been made in the use of GPUs with asymmetric and symmetric cryptographic algorithms more recently with hash functions. This paper conducts a review of previous implementations of AES on GPU and implements the AES algorithm for encryption and decryption with keys of 128, 192 and 256 bits in ECB mode with padding, with variations in the use of available resources in CUDA GPUs. As a nal result, a CUDA implementation was obtained with a resource conguration providing gains in total time of encryption / decryption of up to 32,7 times compared to the used CPU version. vii

SUMÁRIO 1 Introdução........................................................... 1 1.1 Contextualização... 1 1.2 Definição do problema... 2 1.3 Objetivos do projeto... 2 1.4 Apresentação do manuscrito... 2 2 CUDA - Compute Unied Device Architecture........................... 3 2.1 Introdução... 3 2.2 Histórico... 3 2.3 CPU x GPU... 5 2.4 Modelo de programação... 6 2.4.1 Kernels e Hierarquia de Threads... 7 2.4.2 Hierarquia de Memória... 8 2.4.3 Transferência de dados entre GPU e CPU... 9 2.4.4 Barreira de Sincronização... 9 2.5 CUDA C... 10 2.5.1 Pilha de software... 10 2.5.2 Compilação... 10 2.5.3 Qualificadores de funções... 11 2.5.4 Variáveis Built-in... 11 2.5.5 Chamada do Kernel... 12 2.5.6 Qualificadores de Variáveis... 12 2.5.7 Sincronização de Threads... 12 3 AES - Advanced Encryption Standard.................................... 13 3.1 Introdução... 13 3.2 Descrição da Cifra... 13 3.2.1 Transformação AddRoundKey... 15 3.2.2 Transformação SubBytes... 15 3.2.3 Transformação ShiftRows... 16 3.2.4 Transformação MixColumns... 16 3.2.5 Transformação Inversa da AddRoundKey... 16 3.2.6 Transformação invsubbytes... 16 3.2.7 Transformação invshiftrows... 17 viii

3.2.8 Transformação invmixcolumns... 17 3.2.9 Expansão da Chave... 17 3.3 Modos de Operação... 18 3.3.1 Padding... 19 3.4 Table Look-up... 19 3.5 Bit-Slicing... 20 3.6 AES-NI... 21 3.7 AES e CUDA... 22 3.7.1 Manavski (2007)... 22 3.7.2 Harrison e Waldron (2008)... 24 3.7.3 Biagio et al. (2009)... 25 3.7.4 Jang et al. (2011)... 27 4 Desenvolvimento..................................................... 28 4.1 Introdução... 28 4.2 Utilitários... 29 4.2.1 aes_key... 29 4.2.2 aes_enc... 30 4.2.3 aes_dec... 30 4.2.4 aes_enc_file... 30 4.2.5 aes_dec_file... 31 4.3 Plataforma... 32 4.4 Implementação para CPU... 33 4.5 Implementação para GPU CUDA... 33 4.5.1 cuda_aes_nn_global_roll... 34 4.5.2 cuda_aes_nn_global_unroll... 34 4.5.3 cuda_aes_1b_nt_const_const... 34 4.5.4 cuda_aes_nb_nt_const_const... 35 4.5.5 cuda_aes_1b_nt_const_texture... 35 4.5.6 cuda_aes_nb_nt_const_texture... 35 4.5.7 cuda_aes_1b_nt_shared_const... 35 4.5.8 cuda_aes_nb_nt_shared_const... 36 4.5.9 cuda_aes_1b_nt_shared_texture... 36 4.5.10 cuda_aes_nb_nt_shared_texture... 36 5 Resultados Experimentais............................................ 37 5.1 Introdução... 37 5.2 Avaliação roll ou unroll... 37 5.3 Avaliação 1 bloco ou N blocos... 39 5.4 Avaliação das implementações de N blocos... 42 5.5 Avaliação das implementações de memória pinned... 45 5.6 Avaliação das implementações assíncronas... 48 ix

5.7 Avaliação final... 50 5.8 Comparação com trabalhos anteriores... 56 6 Conclusões........................................................... 57 REFERÊNCIAS BIBLIOGRÁFICAS..................................... 59 Anexos................................................................... 62 I Plataforma de Testes................................................ 63 I.1 Máquina 1... 63 I.1.1 Software... 63 I.1.2 Hardware... 63 I.2 Máquina 2... 64 I.2.1 Software... 64 I.2.2 Hardware... 64 II Listagens............................................................. 67 II.1 UTIL... 67 II.2 CUDA_UTIL... 77 II.3 REFERENCE... 91 II.4 REFERENCE_UNROLL... 93 II.5 cuda_aes_nn_global_roll... 97 II.6 cuda_aes_nn_global_unroll... 103 II.7 cuda_aes_1b_nt_const_const... 105 II.8 cuda_aes_nb_nt_const_const... 109 II.9 cuda_aes_1b_nt_const_texture... 114 II.10 cuda_aes_nb_nt_const_texture... 118 II.11 cuda_aes_1b_nt_shared_const... 123 II.12 cuda_aes_nb_nt_shared_const... 127 II.13 cuda_aes_1b_nt_shared_texture... 133 II.14 cuda_aes_nb_nt_shared_texture... 138 x

LISTA DE FIGURAS 2.1 Fermi - Visão Geral da Arquitetura. (NVIDIA, 2011c)... 4 2.2 Fermi - Streaming Multiprocessor (SM)(NVIDIA, 2011c)... 5 2.3 CPU x GPU (NVIDIA, 2012a)... 6 2.4 Escalabilidade Automática (NVIDIA, 2012a)... 7 2.5 Grid formado por blocos de threads (NVIDIA, 2012a)... 8 2.6 Pilha de Software CUDA (NVIDIA, 2008)... 10 3.1 Tabela S-BOX: valores de substituição para o byte xy ( no formato hexadecimal ) (NIST, 2001a)... 16 3.2 Tabela Inversa da S-BOX: valores de substituição para o byte xy (no formato hexadecimal)(nist, 2001a)... 17 3.3 AES cifração Table Look-up (DAEMEN; RIJMEN, 1999)... 19 3.4 AES decifração Table Look-up (DAEMEN; RIJMEN, 1999)... 20 3.5 Rodada da cifração do AES usando Table Look-up (DAEMEN; RIJMEN, 1999)... 20 3.6 Resultados de Harrison e Waldron (2008) com desempenho em Mbit/s (adaptado)... 25 3.7 Resultados de Biagio et al. (2009) com desempenho em Mbit/s (adaptado)... 26 4.1 Utilitário aes_key... 29 4.2 Utilitário aes_enc... 30 4.3 Utilitário aes_dec... 30 4.4 Utilitário aes_enc_le... 31 4.5 Utilitário CUDA aes_enc_le... 31 4.6 Utilitário aes_dec_le... 32 4.7 Utilitário CUDA aes_dec_le... 33 5.1 Tempos de execução em milissegundos no experimento do Tópico 5.3 para a máquina do Tópico I.1... 40 5.2 Tempos de execução em milissegundos por implementação no experimento do Tópico 5.3 para a máquina do Tópico I.1... 41 5.3 Tempos de execução em milissegundos no experimento do Tópico 5.3 para a máquina do Tópico I.2... 41 5.4 Tempos de execução em milissegundos por implementação no experimento do Tópico 5.3 para a máquina do Tópico I.2... 42 5.5 Tempos de execução em milissegundos no experimento do Tópico 5.4 para a máquina do Tópico I.1... 43 xi

5.6 Tempos de execução em milissegundos no experimento do Tópico 5.4 para a máquina do Tópico I.2... 44 5.7 Tempos de execução em milissegundos no experimento do Tópico 5.4 para implementações com tabelas na memória compartilhada para a máquina do Tópico I.1... 44 5.8 Tempos de execução em milissegundos no experimento do Tópico 5.4 para implementações com tabelas na memória compartilhada para a máquina do Tópico I.2... 45 5.9 Tempos de execução em milissegundos do experimento do Tópico 5.5 para a máquina do Tópico I.1... 46 5.10 Tempos de execução em milissegundos do experimento do Tópico 5.5 para a máquina do Tópico I.2... 47 5.11 Tempos totais de execução em milissegundos do experimento do Tópico 5.5 para a máquina do Tópico I.1... 47 5.12 Tempos totais de execução em milissegundos do experimento do Tópico 5.5 para a máquina do Tópico I.2... 48 5.13 Tempos totais de execução em milissegundos do experimento do Tópico 5.6 para a máquina do Tópico I.1... 49 5.14 Tempos totais de execução em milissegundos do experimento do Tópico 5.6 para a máquina do Tópico I.2... 49 I.1 Propriedades da placa gráca 1... 65 I.2 Propriedades da placa gráca 2... 66 xii

LISTA DE TABELAS 2.1 Tipos de memórias... 9 3.1 AES: Combinações de chave, bloco e rodadas... 14 3.2 Resultados de Kasper e Schwabe (2009) para cifração AES-CTR (128 bits) de pacotes de 4096 bytes... 21 3.3 Resultados de INTEL (2010a) para cifração/decifração AES de um bloco de 1024 bytes... 23 3.4 Resultados de INTEL (2010a) para cifração AES-128 usando OpenSSL versão 0.9.8h sem AES-NI... 23 3.5 Resultados de Manavski (2007)... 24 3.6 Resultados de Manavski (2007) com desempenho em Gbit/s... 24 3.7 Resultados de Biagio et al. (2009) com o melhor desempenho em Mbit/s... 27 5.1 Descrição das implementações utilizadas no experimento do Tópico 5.2... 38 5.2 Tempos de execução em milissegundos no experimento do Tópico 5.2 na máquina do Tópico I.1... 38 5.3 Tempos de execução em milissegundos no experimento do Tópico 5.2 na máquina do Tópico I.2... 39 5.4 Descrição das implementações utilizadas no experimento do Tópico 5.3... 40 5.5 Descrição das implementações utilizadas no experimento do Tópico 5.4... 43 5.6 Descrição das implementações pageable e pinned utilizadas no experimento do Tópico 5.5... 46 5.7 Resultados do experimento do Tópico 5.7 da GPU para AES 128 bits na máquina do Tópico I.1... 50 5.8 Resultados do experimento do Tópico 5.7 da GPU para AES 192 bits na máquina do Tópico I.1... 51 5.9 Resultados do experimento do Tópico 5.7 da GPU para AES 256 bits na máquina do Tópico I.1... 51 5.10 Resultados do experimento do Tópico 5.7 da CPU e comparação com a GPU para AES 128 bits na máquina do Tópico I.1... 52 5.11 Resultados do experimento do Tópico 5.7 da CPU e comparação com a GPU para AES 192 bits na máquina do Tópico I.1... 52 5.12 Resultados do experimento do Tópico 5.7 da CPU e comparação com a GPU para AES 256 bits na máquina do Tópico I.1... 53 xiii

5.13 Resultados do experimento do Tópico 5.7 para AES 128 bits na máquina do Tópico I.2... 53 5.14 Resultados do experimento do Tópico 5.7 para AES 192 bits na máquina do Tópico I.2... 54 5.15 Resultados do experimento do Tópico 5.7 para AES 256 bits na máquina do Tópico I.2... 54 5.16 Resultados do experimento do Tópico 5.7 da CPU e comparação com a GPU para AES 128 bits na máquina do Tópico I.2... 55 5.17 Resultados do experimento do Tópico 5.7 da CPU e comparação com a GPU para AES 192 bits na máquina do Tópico I.2... 55 5.18 Resultados do experimento do Tópico 5.7 da CPU e comparação com a GPU para AES 256 bits na máquina do Tópico I.2... 56 5.19 Comparação com trabalhos anteriores para AES 128 bits... 56 xiv

LISTA DE CÓDIGOS FONTES 3.1 Pseudocódigo para cifração do AES (NIST, 2001a)... 14 3.2 Pseudocódigo para decifração do AES (NIST, 2001a)... 14 3.3 Pseudocódigo equivalente para decifração do AES (NIST, 2001a)... 15 3.4 Pseudocódigo para expansão de chave de cifração do AES (NIST, 2001a)... 18 3.5 Pseudocódigo para expansão da chave da decifração(equivalente) AES (NIST, 2001a) 18 II.1 util/aes_key.c... 67 II.2 util/aes_enc.c... 68 II.3 util/aes_dec.c... 69 II.4 util/aes_enc_le.c... 71 II.5 util/aes_dec_le.c... 74 II.6 cuda_util/getdeviceproperties.cu... 77 II.7 cuda_util/cuda_util.cu... 77 II.8 cuda_util/aes_key.cu... 79 II.9 cuda_util/aes_enc.cu... 80 II.10 cuda_util/aes_dec.cu... 82 II.11 cuda_util/aes_enc_le.cu... 83 II.12 cuda_util/aes_dec_le.cu... 87 II.13 reference/aes.c... 91 II.14 reference_unroll/aes.c... 93 II.15 cuda_aes_nn_global_roll/aes.cu... 97 II.16 cuda_aes_nn_global_unroll/aes.cu...103 II.17 cuda_aes_1b_nt_const_const/aes.cu...105 II.18 cuda_aes_nb_nt_const_const/aes.cu...109 II.19 cuda_aes_1b_nt_const_texture/aes.cu...114 II.20 cuda_aes_nb_nt_const_texture/aes.cu...118 II.21 cuda_aes_1b_nt_shared_const/aes.cu...123 II.22 cuda_aes_nb_nt_shared_const/aes.cu...127 II.23 cuda_aes_1b_nt_shared_texture/aes.cu...133 II.24 cuda_aes_nb_nt_shared_texture/aes.cu...138 xv

LISTA DE SÍMBOLOS, NOMENCLATURAS E ABREVIAÇÕES ABNT AES AES-128 AES-192 AES-256 AES-NI ALU API CBC CDT CFB CTR CUDA CPU DDR3 DES DRAM ECB FIPS Gbps Gibps GB GiB GHz GCC GF GPU GPGPU IDE ISA JIT KB KiB LTS Associação Brasileira de Normas Técnicas Advanced Encryption Standard Advanced Encryption Standard com chave de 128 bits Advanced Encryption Standard com chave de 192 bits Advanced Encryption Standard com chave de 256 bits Intel Advanced Encryption Standard New Instructions Arithmetic and Logic Unit Application Program Interface Cipher Block Chaining C/C++ Development Tooling Cipher Feedback Counter Compute Unied Device Architecture Central Processing Unit Double Data Rate Type Three Data Encryption Standard Dynamic Random-Access Memory Eletronic Code Book Federal Information Processing Standards Gigabit por segundo (10 9 bits por segundo) Gibibit por segundo (2 30 bits por segundo) Gigabyte (10 9 bytes) Gibibyte (2 30 bytes) GigaHertz (10 9 repetições por segundo) GNU Compiler Collection Corpo de Galois Graphic Processinc Unit General-purpose Computations on GPU Integrated Development Environment Instruction Set Architecture Compilador Just-In-Time KiloByte (1000 bytes) KibiByte (1024 bytes) Long Term Support xvi

ms milissegundo MB MegaByte (1000*1000 bytes) MiB MebiByte (1024*1024 bytes) Mbps Megabit por segundo(10 6 bits por segundo) Mibps Mebibit por segundo(2 20 bits por segundo) N b tamanho do bloco de entrada do AES em palavras de 32 bits N k tamanho da chave do AES em palavras de 32 bits N r número de rodadas (rounds) do AES NIST National Institute of Standards and Technology OFB Output Feedback OpenGL Open Graphics Library OpenSSL Open Secure Sockets Layer PCI Peripheral Component Interconnect Express PTX Parallel Thread execution PUBS Publications S-Box Caixa de substituição do AES SHA-3 Secure Hash Algorithm versão 3 SIMD Single Instruction Stream - Multiple Data Stream SIMT Single Instruction Stream - Multiple Threads SM Streaming Multiprocessor SSL Secure Sockets Layer TLS Transport Layer Security TI Tecnologia da Informação U.S United States UnB Universidade de Brasília XOR Operação booleana Ou-Exclusivo xvii

Capítulo 1 Introdução 1.1 Contextualização Este capítulo apresenta a motivação deste trabalho, elenca os objetivos a serem alcançados e por m, mostra a estruturação do manuscrito. Graphics Processing Units (GPUs) são coprocessadores que tradicionalmente realizam a renderização de informações bidimensionais e tridimensionais para exibição para o usuário. O crescimento da indústria de jogos e o aumento da demanda por grácos mais realistas e com renderização em tempo real forçou as GPUs a proverem unidades de processamento paralelas mais rápidas. Este esforço levou ao surgimento de dispositivos que sobrepujaram as CPUs em aplicações especícas, como no caso dos jogos, com a relação custo-benefício aceitável devido a produção em escala destes dispositivos. Não demorou até a comunidade cientíca e os programadores perceberem que este poder computacional poderia ser utilizado para outras funções além das originais de computação gráca. Em Harris (2003) foi introduzido o termo General-purpose Computations on GPUs (GPGPU) para se referir a estas aplicações não grácas que usavam o poder computacional das GPUs. Naquele momento, programar GPGPU signicava expressar seus algoritmos em termos de operações sobre dados grácos, pixels e vetores. Este paradigma mudou quando dois importantes fabricantes de GPUs, NVIDIA e AMD, alteraram a arquitetura de hardware dos seus dispositivos grácos para uma plataforma de computação multi-core, com a introdução das unied processing units nas placas grácas. As GPU puderam então suportar um conjunto de instruções de propósito genérico, promovendo o surgimento de linguagens de programação, ferramentas e frameworks para usufruir desse potencial computacional. Os benefícios do uso de GPUs são vários, mas pode-se destacar sua fácil integração em plataformas distintas como desktops, notebooks, servidores e até mesmo dispositivos móveis, sem quaisquer alterações fundamentais no hardware. GPUs estão disponíveis no mercado em uma vasta gama de níveis de desempenho, pode-se escolher uma de acordo com suas necessidades. Quando não estão sendo utilizadas para jogos ou na renderização de interfaces grácas elegantes cam ociosas, fazendo sentido usá-las como coprocessadores de operações custosas. 1

No campo da criptograa já foram realizados esforços no uso de GPUs com algoritmos criptográcos simétricos e assimétricos e mais recentemente com as funções de hash. Este trabalho realiza uma revisão das implementações anteriores do AES sobre GPUs e implementa o algoritmo AES para cifração e decifração com chaves de 128, 192 e 256 bits no modo ECB com padding, com variações no uso dos recursos disponíveis nas GPUs CUDA. 1.2 Denição do problema Usar o poder computacional provido pelas GPUs CUDA no uso do algoritmo simétrico AES, atentando para as diferenças arquiteturais entre GPU CUDA e CPU e buscando identicar a combinação de recursos e funcionalidades disponíveis nas placas CUDA para obter o melhor desempenho do AES. 1.3 Objetivos do projeto Realizar um estudo da arquitetura CUDA da NVIDIA, focando nos recursos e funcionalidades que possam ser explorados na implementação do algoritmo AES. Revisitar os trabalhos anteriores sobre o uso do algoritmo simétrico AES sobre dispositivos CUDA. Realizar a implementação do AES sobre esta arquitetura, elencando possibilidades de ganho de desempenho em comparação com uma implementação em CPU. 1.4 Apresentação do manuscrito No Capítulo 2, é feita uma descrição da arquitetura CUDA, focando nos seus recursos e funcionalidades. No Capítulo 3, é apresentada uma revisão sobre o AES e alguns trabalhos anteriores que zeram uso do AES em GPUs. Em seguida, o Capítulo 4 descreve a metodologia empregada no desenvolvimento do projeto e a implementação do AES. Resultados experimentais são discutidos no Capítulo 5, e por m as conclusões no Capítulo 6. 2

Capítulo 2 CUDA - Compute Unied Device Architecture 2.1 Introdução Este capítulo tem a função de apresentar a arquitetura CUDA, modelo de memória, modelo de execução e seus paradigmas de implementação Compute Unied Device Architecture (CUDA) é uma plataforma de computação paralela de propósito geral que tira proveito das unidades de processamento gráco (GPU) NVIDIA para resolver problemas computacionais que possam ser paralelizáveis. Possui um conjunto de instruções chamado CUDA ISA (Instruction Set Architecture) e o mecanismo de computação paralela na GPU. Para programar segundo a arquitetura CUDA, os desenvolvedores utilizam C com um conjunto de extensões, o chamado CUDA Toolkit, que pode ser então executado em um processador compatível com CUDA. Outras linguagens também são admitidas, como C++ e FORTRAN. Em versões antigas do CUDA Toolkit, era possível desenvolver mesmo sem ter o hardware necessário, usando um emulador, mas a partir da versão 3.0, essa funcionalidade não é mais suportada. 2.2 Histórico As primeiras GPUs foram projetadas como aceleradores grácos, suportando somente pipelines com funções xas especícas 1. Fazer uso das GPU para outros propósitos além das grácas, demandava o uso de linguagens de programação grácas como a OpenGL 2. Os desenvolvedores tinham que mapear cálculos cientícos a problemas que poderiam ser representados por triângulos e polígonos. Em Buck et al. (2004) foi apresentado um sistema de computação de propósito geral em 1 Etapas pelas quais um dado gráco é processado por uma GPU, tais como, operações com vértices, montagem de primitivas, rasterização, operação com fragmentos e composição. 2 OpenGL (Open Graphics Library) é uma API livre utilizada na computação gráca, para desenvolvimento de aplicativos grácos, ambientes 3D, jogos, entre outros.(wikipédia, 2012b) 3

hardwares grácos programáveis, chamado Brook. Este sistema estendia a linguagem C para incluir construções de paralelismo de dados, permitindo o uso das GPUs como coprocessadores de uxo 3. Neste trabalho foi proposto um compilador e um runtime que abstraía e virtualizava muitos aspectos dos dispositivos grácos. A NVIDIA sabia que um hardware extremamente rápido tinha que ser combinado a ferramentas intuitivas de software e hardware, e por isso convidou Ian Buck para juntar-se à empresa e começar a desenvolver uma solução para executar o C na GPU de forma uida. Juntando o software e o hardware, a NVIDIA apresentou o CUDA em 2006, a primeira solução do mundo para computação de propósito geral em GPUs (NVIDIA, 2012c). Atualmente todas as GPUs da NVIDIA suportam CUDA. CUDA não é uma arquitetura computacional no sentido de um conjunto de instruções e um conjunto de registradores especícos. Binários compilados para uma GPU CUDA não necessariamente executarão em todas as GPUs. A NVIDIA deniu o termo compute capability para descrever as funcionalidades suportadas por um hardware CUDA. A primeira GPU CUDA, GeForce 8800, possui a compute capability 1.0, e em 2011 a NVIDIA lançou GPUs com a compute capability 2.x, também conhecidas como arquitetura Fermi, veja Figura 2.1. Mais detalhes sobre as funcionalidades correspondentes a cada compute capability encontram-se em NVIDIA (2012a, Apêndice F, pág. 135). Figura 2.1: Fermi - Visão Geral da Arquitetura. (NVIDIA, 2011c) Uma GPU CUDA consiste de múltiplos streaming multiprocessor (SMs), no caso da arquitetura 3 Unidade de processamento que sobre um conjunto de dados (uxo) aplica um série de operações (funções de kernel). Esta relacionado ao paradigma de programação single instruction, multiple data (SIMD). 4

Figura 2.2: Fermi - Streaming Multiprocessor (SM)(NVIDIA, 2011c) Fermi são 16 SMs, conforme exemplicado na Figura 2.1. Cada SM contém vários núcleos (core) CUDA, 8 cores por SM nas placas com compute capability 1.x, 32 cores por SM nas placas com compute capability 2.0 e 48 cores por SM nas placas com compute capability 2.1, cada core é o responsável por executar os cálculos aritméticos. Na Figura 2.2 está exemplicado um SM na arquitetura Fermi, contendo 32 CUDA cores. 2.3 CPU x GPU De forma simplista as GPUs são projetadas com mais transistores dedicados ao processamento de dados, as chamadas unidades lógicas aritméticas (ALU), do que para caching e controle de uxo, visando executar vários uxos de instruções o mais rápido possível, enquanto CPUs gastam seus transistores com a nalidade de aumentar a velocidade de execução de um uxo de instruções. CPUs suportam uma ou duas threads por core, enquanto GPUs CUDA suportam até 1024 threads por streaming multiprocessor. O custo de troca (switch) de uma thread na CPU é de algumas centenas de ciclos, enquanto as GPUs não tem custo nas trocas de threads, na realidade as threads são trocadas a cada ciclo de relógio. As GPUs usam o conceito de Single Instruction Stream - Multiple Data Stream (SIMD) para explorar o poder computacional destes ALUs, executando um único uxo de instruções em múltiplos uxos de dados independentes (FLYNN, 1966). Em GPUs CUDA ocorre um variação 5

na abordagem SIMD, um conjunto de threads executa o mesmo uxo de instruções em diferentes conjuntos de dados, NVIDIA chama essa abordagem de Single Instruction Stream - Multiple Threads (SIMT) (NVIDIA, 2012a, pág.61). Essa comparação arquitetural simplicada pode ser exemplicada pela Figura 2.3. Figura 2.3: CPU x GPU (NVIDIA, 2012a) Mais especicamente, a GPU é especialmente adequada para resolver os problemas que podem ser expressos como o mesmo programa sendo executado em muitos elementos de dados em paralelo, programas com uma alta intensidade de cálculos aritméticos comparados com as operações de acesso à memória. Como o mesmo programa é executado para cada elemento de dados, há uma menor necessidade de controle de uxo sosticado, e como é executado em muitos elementos de dados e tem intensidade aritmética elevada, a latência de acesso de memória pode ser ocultada com o uso cálculos intensos em vez de grandes caches de dados como ocorre nas CPUs. 2.4 Modelo de programação O modelo de programação paralela CUDA baseia-se em três abstrações: uma hierarquia de grupos de threads, hierarquia de memórias compartilhadas, e barreiras de sincronização. Essas abstrações são disponibilizadas ao programador como um conjunto mínimo de extensões da linguagem de programação. Essas abstrações guiam o programador a dividir o problema em grandes sub-problemas que podem ser resolvidos de forma independente em paralelo por blocos de threads, e cada sub-problema em pedaços menores que podem ser resolvidos de forma cooperativa em paralelo por todos as threads dentro do bloco. Essa decomposição preserva a nalidade inicial do programa permitindo que threads cooperem na resolução dos sub-problemas, e ao mesmo tempo habilitando automaticamente a escalabilidade do problema. Cada bloco de threads pode ser designado para ser executado em qualquer multiprocessador disponível dentro de uma GPU, e em qualquer ordem, concorrentemente ou sequencialmente. Este modelo de programação escalável permite que um programa CUDA seja executado em 6

uma variedade de hardwares CUDA, desde placas de alto-desempenho até placas mais baratas, simplesmente deixando com o runtime CUDA a responsabilidade de determinar o total de multiprocessadores sicamente disponíveis em um hardware. Como pode ser exemplicado na Figura 2.4. Figura 2.4: Escalabilidade Automática (NVIDIA, 2012a) 2.4.1 Kernels e Hierarquia de Threads No modelo de programação CUDA o conjunto de instruções que serão executados devem ser distinguidos e agrupados por funções. Existem funções que são executadas na CPU, ou host, funções que são executadas na GPU, ou device. A função que o host chama para dar início a uma execução no device é chamada de kernel. A distinção entre as funções é feita por qualicadores explicados no Tópico 2.5.3. Um kernel é mapeado por um conjunto de threads, que são agrupadas em blocos (blocks), e estes blocos são agrupados em um grid. Essa conguração contendo o número de blocos em cada grid e o número de threads em cada bloco é passada na chamada do kernel, conforme explicado no Tópico 2.5.5. Threads pertencentes a um bloco rodam em um mesmo SM, mas uma SM pode rodar múltiplos blocos concorrentemente. Internamente ao device, os blocos são divididos em grupos de 32 threads, chamados warps 4, as threads pertencentes a um warp são executadas em sincronia. As dimensões do grid e dos blocos podem ser unidimensionais, bidimensionais ou tridimensionais, no exemplo da Figura 2.5 está denido um grid bidimensional, formado por blocos também bidimensionais. Dentro de cada thread estão disponíveis variáveis built-in que designam unica- 4 Este termo vem da tecelagem, considerado pela NVIDIA a primeira tecnologia multi-thread. 7

mente a qual bloco ela pertence e o seu próprio identicador, além das dimensões dos blocos e grids, conforme explicado no Tópico 2.5.4. Figura 2.5: Grid formado por blocos de threads (NVIDIA, 2012a) 2.4.2 Hierarquia de Memória Otimizar o desempenho de aplicações CUDA geralmente envolve otimizações no acesso de dados, que inclui o uso apropriado dos diferentes tipos de memória. Cada tipo de memória dentro de uma GPU possui uma forma distinta de leitura e escrita, tempo de vida, escopo e tempo de acesso. A Tabela 2.1 apresenta os diferentes tipos de memória presentes em um device CUDA. Os bancos de registradores possuem o melhor tempo de acesso porém quanto mais threads são executadas menos registradores cam disponíveis para as threads. Encontrar o número ótimo de threads rodando concorrentemente em um SM é um passo crucial para atingir-se um bom desempenho. Cada SM possui vários KB de memória compartilhada (shared) de acesso rápido, acessível por todas as threads em um SM. Esta memória serve para troca de dados entre threads de um bloco com latência de acesso tão baixa quanto a dos registradores, mas a vazão (throughput) depende do padrão de acesso. A memória compartilhada é organizada em 16 bancos de memória, se duas threads pertencentes a um mesmo half-warp (16 threads) leem ou armazenam em diferentes 8

Tabela 2.1: Tipos de memórias Memória on/o chip Acesso Escopo Tempo de Vida Registrador on leitura/escrita thread thread Local o leitura/escrita thread thread Compartilhada on leitura/escrita bloco bloco Global o leitura/escrita grids + host alocação do host Constante o leitura grids + host alocação do host Textura o leitura grids + host alocação do host endereços dentro do mesmo banco de memória na mesma instrução, então essas requisições são serializadas. Este evento é chamado de conito de banco (bank conicts). 2.4.3 Transferência de dados entre GPU e CPU Ambos host e device possuem suas próprias DRAM 5. Todo o gerenciamento de memória realizado por um aplicativo (global, constantes e texturas), passa pelo runtime do CUDA, incluindo alocação, desalocação, e transferência de dados entre as memórias do host e do device. Comunicação entre CPU e GPU é realizada pela transferência de dados entre a memória do host e a memória do device ou mapeando uma memória page-locked (também chamada de pinned) no espaço de endereços da GPU. Transferência de dados assíncrona entre memória page-locked do host e a memória do device pode ser sobreposta (overlap) com execuções na CPU, e em dispositivos CUDA desde a compute capability 1.1 essas transferências podem ser sobrepostas com execuções na GPU. 2.4.4 Barreira de Sincronização Se uma thread necessita visualizar o valor de uma variável shared que foi escrita por outra thread, pode ocorrer uma inconsistência, pois a thread com a leitura pode acontecer antes da thread de escrita. Para evitar esse problema é necessário usar uma barreira de sincronização antes da leitura da variável, desta forma, quando a execução do programa encontrar essa barreira de sincronização ele aguardará a chegada de todas as threads do bloco que estão em execução neste ponto para poder prosseguir com a execução do programa, e consequentemente com a leitura da variável. 9

Figura 2.6: Pilha de Software CUDA (NVIDIA, 2008) 2.5 CUDA C 2.5.1 Pilha de software A pilha de software CUDA (Figura 2.6) é composta por: Bibliotecas CUDA: conjunto de bibliotecas de uso genérico como CUBLAS (implementação da Basic Linear Algebra Subprograms), CUFFT (implementação da Transformada Rápida de Fourier), etc; Runtime CUDA: API de alto-nível que facilita a gerência de código para o device provendo inicialização implícita, gerência de contexto e gerência de módulos; Driver CUDA: API de baixo-nível, requer mais codicação, é mais complexa de programar e depurar, mas prove um nível melhor de controle e é independente de linguagem pois trata somente com binários CUDA. O programador deve decidir qual API utilizar pois são mutuamente excludentes (NVIDIA, 2008). 2.5.2 Compilação Primeiramente, o compilador separa as partes do programa que rodam no host das partes que rodam no device. As partes que rodam no host são compiladas com os compiladores C ou C++ para a respectiva arquitetura do host. As partes que rodam no device são traduzidas para uma linguagem intermediária chamada Parallel Thread execution(ptx). Esse código PTX é compatível entre as revisões menores de uma determinada compute capability. O driver da GPU contém um 5 Dynamic random-access memory 10

compilador JIT 6 para essa linguagem intermediária. Códigos que precisam rodar em hardwares com diferentes compute capability precisam gerar diferentes versões desse código PTX, a compilação nal para o código binário será executada pelo respectivo driver. Esta última compilação pode também ser realizada oine, para produzir binários para uma arquitetura especíca da GPU. 2.5.3 Qualicadores de funções Especicam onde uma função é executada e de onde pode ser chamada (NVIDIA, 2012a, pág. 81): device : declara funções que são executadas no device, e só podem ser chamadas a partir do device; global : declara funções kernel, são executadas no device, e só podem ser chamadas a partir do host. Devem apresentar retorno do tipo void. Deve ser especicada a sua conguração de execução, conforme Tópico 2.5.5; host : declara funções que são executadas no host, e só podem ser chamadas a partir do host. Caso a função seja declarada sem nenhum qualicador, ela será considerada do tipo host por padrão. Nos casos, em que a função deve ser compilada para o device e para o host os quali- cadores host e device são usados combinados. Já os qualicadores global e host não podem ser usados juntos. 2.5.4 Variáveis Built-in Servem para especicar o grid, a dimensão dos blocos e os índices das threads. Sendo válidas apenas dentro das funções que são executadas pelo device(gpu) (NVIDIA, 2012a, pág. 86). Essas variáveis são: griddim: Variável do tipo dim3 e corresponde a dimensão do grid; blockidx: Variável do tipo uint3 e corresponde ao índice do bloco no grid; blockdim: Variável do tipo dim3 e corresponde a dimensão do bloco; threadidx: Variável do tipo uint3 e corresponde ao índice da thread no bloco; warpsize: Variável do tipo básico int e contém o tamanho do warp em threads. O tipo uint3 é utilizado para designar um vetor contendo três elementos do tipo básico int, cada um dos elementos é acessado pela notação var.x, var.y e var.z. O tipo dim3 corresponde 6 Compilador just-in-time é um tradutor que converte, em tempo de execução, instruções de um formato para outro, por exemplo, no caso da linguagem Java, de bytecode para código de máquina.(wikipédia, 2012a) 11

a um vetor de inteiros do tipo uint3 especializado para a denição de dimensões, os elementos não especicados no vetor são inicializados com o valor 1. Ambos os tipos estão disponíveis na biblioteca de runtime do CUDA. Para nenhuma das variáveis built-in é possível realizar atribuição de valores. 2.5.5 Chamada do Kernel As funções declaradas com o qualicador global representam o kernel e na sua chamada devem ser denidos alguns parâmetros para a execução da função (NVIDIA, 2012a, pág. 111). Essa conguração é expressa da seguinte forma Dg, Db, NS, S, onde : Dg: variável do tipo dim3 e especica a dimensão e o tamanho do grid; Db: variável do tipo dim3 e especica a dimensão e o tamanho de cada bloco; NS: variável do tipo size_t e especica o tamanho, em bytes, do espaço que será alocado dinamicamente na memória compartilhada por bloco, esse argumento é opcional e seu valor padrão é 0; S: variável do tipo cudastream_t e especica o stream associado ao kernel, esse argumento é opcional e seu valor padrão é 0. 2.5.6 Qualicadores de Variáveis Especicam a localização na memória de uma variável. Os seguintes qualicadores de variáveis estão disponíveis (NVIDIA, 2012a, pág. 82): device : declara variáveis que devem residir no device e na memoria global; constant : declara variáveis que devem residir no espaço de memoria de constante; shared : declara variáveis que devem residir no espaço de memória de compartilhado. 2.5.7 Sincronização de Threads A sincronização de threads explícita é realizada pelo comando syncthreads(), esta é uma operação que pode impactar no desempenho, pois força o SM a car ocioso aguardando as outras threads chegarem ao ponto de sincronização. Como um warp executa uma instrução simples por vez e threads dentro de um warp são implicitamente sincronizadas, isto pode ser usado para omitir as instrução syncthreads() visando melhorar o desempenho (NVIDIA, 2012a, pág. 77). 12

Capítulo 3 AES - Advanced Encryption Standard 3.1 Introdução Neste capítulo é apresentado algoritmo criptográ- co AES e alguns aspectos de sua implementação em software. Em Criptograa, o Advanced Encryption Standard (AES, ou Padrão de Criptograa Avançada), também conhecido por Rijndael 1, é uma cifra de bloco adotada como padrão de criptograa pelo governo dos Estados Unidos. O AES foi anunciado pelo NIST (Instituto Nacional de Padrões e Tecnologia dos EUA) como U.S. FIPS PUB (FIPS 197) em 26 de Novembro de 2001, depois de 5 anos de um processo de padronização (NIST, 2001a). Tornou-se um padrão efetivo em 26 de Maio de 2002. É amplamente utilizado em todo o ecossistema de hardware e software para proteger o tráfego de rede, dados pessoais, e infraestrutura corporativa de TI. 3.2 Descrição da Cifra Todos os bytes no algoritmo AES são interpretados como elementos de um corpo nito. Esses elementos são adicionados ou multiplicados seguindo as denições matemáticas descritas em NIST (2001a, pág. 10-13). Os seguintes operadores são denidos, para adição e para multiplicação. O AES opera sobre um arranjo bidimensional de bytes com 4x4 posições, denominado de estado (state). O tamanho do bloco de entrada, bloco de saída e do estado é de 128 bits. Este tamanho é representado por N b = 4, que reete o número de palavras de 32 bits que o compõe, ou o número de colunas da visão bidimensional do estado. O tamanho da chave de cifração/decifração é de 128, 192 ou 256 bits. Este tamanho é representado por N k = 4, 6, ou 8, que reete o número de palavras de 32 bits que o compõe. É comum denominar o AES dependentemente do tamanho de sua chave, surgindo os nomes AES-128, AES-192 e AES-256. 1 Nome formado da fusão dos nomes de seus criadores Vincent Rijmen e Joan Daemen 13

O número de rodadas (rounds) a ser executado sobre um estado é dependente do tamanho da chave (Tabela 3.1). Este número é representado por N r = 10, 12 ou 14. Tabela 3.1: AES: Combinações de chave, bloco e rodadas Tamanho da Chave (N k ) Tamanho do Bloco (N b ) Número de rodadas (N r ) AES-128 4 4 10 AES-192 6 4 12 AES-256 8 4 14 O processo de cifração, descrito no Algoritmo 3.1, faz uso da chave de cifração expandida, conforme o Algoritmo 3.4, e de 4 transformações que são aplicadas sobre o estado, conforme Tópicos 3.2.1, 3.2.2, 3.2.3 e 3.2.4. Em NIST (2001a) esse processo é denominado Cipher. O processo de decifração, descrito no Algoritmo 3.2, faz uso da mesma chave de cifração expandida gerada pelo Algoritmo 3.4 e das transformações inversas da cifração que são aplicadas sobre o estado, conforme Tópicos 3.2.5, 3.2.6, 3.2.7 e 3.2.8. Em NIST (2001a) esse processo é denominado Inverse Cipher. Um processo equivalente para a decifração é fornecido em NIST (2001a). Este processo (Algoritmo 3.3) oferece uma estrutura mais eciente do que o processo descrito no Algoritmo 3.2, porém exige uma alteração na chave de cifração expandida, aplicando os Algoritmos 3.4 e 3.5 em sequência para gerar as chaves de rodada que serão usadas neste algoritmo. Em NIST (2001a) esse processo é denominado Equivalent Inverse Cipher. Código fonte 3.1: Pseudocódigo para cifração do AES (NIST, 2001a) Cipher ( byte i n [ 4 Nb ], byte out [ 4 Nb ], word w[ Nb ( Nr+1) ] ) begin byte s t a t e [ 4,Nb ] s t a t e = i n AddRoundKey( s t a t e, w[ 0, Nb 1 ] ) for round = 1 step 1 to Nr 1 SubBytes ( s t a t e ) ShiftRows ( s t a t e ) MixColumns ( s t a t e ) AddRoundKey( s t a t e, w[ round Nb, ( round + 1) Nb 1 ] ) end for SubBytes ( s t a t e ) ShiftRows ( s t a t e ) AddRoundKey( s t a t e, w[ Nr Nb, ( Nr + 1) Nb 1 ] ) out = s t a t e end Código fonte 3.2: Pseudocódigo para decifração do AES (NIST, 2001a) InvCipher ( byte i n [ 4 Nb ], byte out [ 4 Nb ], word w[ Nb ( Nr+1) ] ) 14

begin byte s t a t e [ 4,Nb ] s t a t e = i n AddRoundKey( s t a t e, w[ Nr Nb, ( Nr+1) Nb 1]) for round = Nr 1 step 1 downto 1 InvShiftRows ( s t a t e ) InvSubBytes ( s t a t e ) AddRoundKey( s t a t e, w[ round Nb, ( round+1) Nb 1]) InvMixColumns ( s t a t e ) end for InvShiftRows ( s t a t e ) InvSubBytes ( s t a t e ) AddRoundKey( s t a t e, w[ 0, Nb 1]) out = s t a t e end Código fonte 3.3: Pseudocódigo equivalente para decifração do AES (NIST, 2001a) EqInvCipher ( byte i n [ 4 Nb ], byte out [ 4 Nb ], word dw [ Nb ( Nr+1) ] ) begin byte s t a t e [ 4,Nb ] s t a t e = i n AddRoundKey( s t a t e, dw [ Nr Nb, ( Nr+1) Nb 1]) for round = Nr 1 step 1 downto 1 InvSubBytes ( s t a t e ) InvShiftRows ( s t a t e ) InvMixColumns ( s t a t e ) AddRoundKey( s t a t e, dw [ round Nb, ( round+1) Nb 1]) end for InvSubBytes ( s t a t e ) InvShiftRows ( s t a t e ) AddRoundKey( s t a t e, dw [ 0, Nb 1]) out = s t a t e end 3.2.1 Transformação AddRoundKey Nesta transformação o estado é combinado com a chave de rodada, usando uma operação XOR byte a byte. 3.2.2 Transformação SubBytes Nesta transformação cada byte do estado é substituído por outro de acordo com uma tabela de referência, denominada S-Box ( Figura 3.1). A tabela S-Box é inversível e é construída calculando o inverso multiplicativo em GF (2 8 ) para cada um dos bytes, sendo que 00 é mapeado em si mesmo, e então aplicando uma transformação am em GF (2), descrita em NIST (2001a). 15

Figura 3.1: Tabela S-BOX: valores de substituição para o byte xy ( no formato hexadecimal ) (NIST, 2001a) 3.2.3 Transformação ShiftRows Nesta transformação são alteradas as linhas do estado, deslocando os bytes em cada linha de um determinado número de posições. A primeira linha ca inalterada. Cada byte da segunda linha é rotacionado à esquerda de uma posição. Similarmente, a terceira e quarta linhas são rotacionadas à esquerda de duas e de três posições respectivamente. 3.2.4 Transformação MixColumns Nesta transformação cada coluna do estado é combinada usando uma transformação linear inversível. Cada coluna é tratada como um polinômio em GF (2 8 ) e é então multiplicado em módulo x 4 + 1 pelo polinômio xo a(x) = {03}x 3 + {01}x 2 + {01}x + {02}, sendo os coecientes de a(x) bytes no formato hexadecimal no corpo nito GF (2 8 ). 3.2.5 Transformação Inversa da AddRoundKey A transformação inversa da AddRoundKey é ela mesma, pois trata-se de uma simples operação XOR byte a byte. 3.2.6 Transformação invsubbytes Nesta transformação cada byte do estado é substituído por outro de acordo com uma tabela inversa da tabela referência S-Box( Figura 3.2). Esta tabela é obtida pela inversa da transformação am em GF (2) descrita em NIST (2001a) seguida pelo cálculo do inverso multiplicativo em GF (2 8 ). 16

Figura 3.2: Tabela Inversa da S-BOX: valores de substituição para o byte xy (no formato hexadecimal)(nist, 2001a) 3.2.7 Transformação invshiftrows Nesta transformação são alteradas as linhas do estado, deslocando os bytes em cada linha de um determinado número de posições. A primeira linha ca inalterada. Cada byte da segunda linha é rotacionado à direita de uma posição. Similarmente, a terceira e quarta linhas são rotacionadas à direita de duas e de três posições respectivamente. 3.2.8 Transformação invmixcolumns Nesta transformação cada coluna do estado é combinada usando uma transformação linear inversível. Cada coluna é tratada como um polinômio em GF (2 8 ) e é então multiplicado em módulo x 4 + 1 pelo polinômio xo a 1 (x) = {0b}x 3 + {0d}x 2 + {09}x + {0e}, sendo os coecientes de a 1 (x) bytes no formato hexadecimal no corpo nito GF (2 8 ). 3.2.9 Expansão da Chave A chave de cifração é expandida usando-se o Algoritmo 3.4, neste processo são gerados um total de N b (N r + 1) palavras de 32 bits. A função SubWord() recebe 4 bytes e aplica a tabela S-BOX (Figura 3.1) em cada um dos bytes para gerar sua saída. A função RotWord() recebe uma palavra de 4 bytes e a rotaciona à esquerda para gerar sua saída. O vetor constante de rodada, Rcon[i], contém os valores [{02} i 1, {00}, {00}, {00}], onde as operações de multiplicação ocorrem no corpo GF (2 8 ) módulo o polinômio m(x) = x 8 + x 4 + x 3 + x + 1, e o índice i inicia-se em 1. 17

Código fonte 3.4: Pseudocódigo para expansão de chave de cifração do AES (NIST, 2001a) KeyExpansion ( byte key [ 4 Nk ], word w[ Nb ( Nr+1) ], Nk) begin word temp i =0 while ( i < Nk) w[ i ] = word( key [ 4 i ], key [ 4 i +1], key [ 4 i +2], key [ 4 i +3]) i = i +1 end while i = Nk while ( i < Nb ( Nr+1) ) temp = w[ i 1] i f ( i mod Nk = 0) temp = SubWord(RotWord( temp ) ) xor Rcon [ i /Nk ] else i f (Nk > 6 and i mod Nk = 4) temp = SubWord( temp ) end i f w[ i ] = w[ i Nk ] xor temp i=i +1 end while end A chave de decifração usada no Algoritmo 3.3 é gerada aplicando primeiramente o Algoritmo 3.4 e em seguida o Algoritmo 3.5. Cabe ressaltar uma mudança na transformação InvMixColumns usada nesse algoritmo, a transformação original descrita no Tópico 3.2.8 opera sobre um vetor bidimensional, o estado, no Algoritmo 3.5 a transformação InvMixColumns opera sobre um vetor unidimensional. Código fonte 3.5: Pseudocódigo para expansão da chave da decifração(equivalente) AES (NIST, 2001a) for i = 0 step 1 to ( Nr+1) Nb 1 dw [ i ] = w[ i ] end for for round = 1 step 1 to Nr 1 InvMixColumns (dw [ round Nb, end for ( round+1) Nb 1]) 3.3 Modos de Operação Existem cinco modos de operação para as cifras de bloco recomendados em NIST (2001b): Electronic Codebook (ECB), Cipher Block Chaining (CBC), Cipher Feedback (CFB), Output Feedback (OFB) e Counter (CTR). Para as implementações do algoritmo AES que fazem uso de paralelismo são mais apropriados os seguintes modos de operação, ECB e CTR para cifração e ECB, CBC, CFB e CTR para decifração. Cabe ressaltar que o modo de operação ECB não é seguro para aplicações práticas, contudo é adequado para ns de medição de desempenho de cifração/decifração. 18

3.3.1 Padding Os modos de operação ECB e CBC requerem que a sua entrada seja um múltiplo do tamanho do bloco. Se o tamanho do texto a ser cifrado não é um múltiplo do tamanho bloco é necessário completar o bloco antes da cifração (padding), e no momento da decifração esse padding deve ser removido após o nal do processo. Em Kaliski (2000) e Kaliski (1998) é proposto o seguinte método de padding: 1. Determinar T AM, o tamanho do texto a ser cifrado; 2. Determinar P AD, o quanto falta para T AM ser um múltiplo do tamanho do bloco (16 bytes no caso do AES); 3. Completar o último bloco do texto a ser cifrado com P AD bytes de valor P AD; 4. Caso T AM seja um múltiplo de 16 (dezesseis), um bloco adicional contendo 16 bytes de valor 16 é concatenado ao texto a ser cifrado. 3.4 Table Look-up Em Daemen e Rijmen (1999) no tópico que trata sobre aspectos de implementação do AES em processadores de 32 bits é sugerida a combinação dos diferentes passos de uma rodada do AES em um conjunto de tabelas. São denidas 4 tabelas, T 0, T 1, T 2 e T 3 (Figura 3.3), cada uma contendo 256 palavras de 4 bytes totalizando 4KiB de espaço total. De modo análogo ao processo de cifração, as tabelas da Figura 3.4 representam as table look-up para a decifração. Nas Figuras 3.3 e 3.4 a função S [a] é a aplicação da transformação SubBytes, a função is [a] é a aplicação da transformação invsubbytes e o operador é a multiplicação no corpo nito GF (2 8 ) denido em NIST (2001a, pág. 10-13). S [a] 02 S [a] 03 T 0 [a] = S [a] 01 S [a] 01 T 1 [a] = S [a] 02 S [a] 01 S [a] 03 S [a] 01 S [a] 01 S [a] 01 T 2 [a] = S [a] 03 S [a] 02 T 3 [a] = S [a] 01 S [a] 03 S [a] 01 S [a] 02 Figura 3.3: AES cifração Table Look-up (DAEMEN; RIJMEN, 1999) Considerando a i,j o estado na entrada de uma rodada, b i,j o estado na saída de uma rodada e k j a chave expandida da rodada, sendo 0 <= i, j < 4 com i representando a linha do estado e j a coluna, e usando essas tabelas (Figura 3.3), tem-se que a transformação desta rodada pode ser expressa pela Figura 3.5. 19