Ejemplo n.º 1
0
void destruirArvore(No **arvore) {
	if(*arvore != NULL) {
		destruirArvore(&((*arvore)->f0));
		destruirArvore(&((*arvore)->f1));
		free(*arvore);
		*arvore = NULL;
	}
}
Ejemplo n.º 2
0
int main( int argc, char *argv[] )
{
    unsigned int itr;

    int operacao;
    int verbose;
    int juntar;
    char * chave_file;
    char * entrada_file;
    char * saida_file;

    octeto Nb,Nk,Nr;
    octeto bloco[4*8];
    octeto chave[4*8*15];

    int worldsize, rank;
    MPI_Status status;
    MPI_File chave_handle;
    MPI_File entrada_handle;
    MPI_File saida_handle;

    MPI_Offset entrada_bytes;
    unsigned int numero_blocos;
    unsigned int blocos_processo;
    MPI_Offset bloco_byte_inicio;
    MPI_Offset bloco_byte_fim;
    MPI_Offset iterador;

    Tabela * tabela;
    octeto * tabelaEmpacotada;
    unsigned int proc;
    unsigned int tamanho_tabela;
    Tabela * tabela2;
    unsigned int no_proc;
    unsigned int no_resto;
    unsigned int i;
    BTreeNode * node;
    Indice * indice;


    MPI_Init(&argc,&argv);

    MPI_Comm_size(MPI_COMM_WORLD,&worldsize);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    operacao = INDEFINIDA;
    verbose = 0;
    juntar = 0;
    chave_file = NULL;
    entrada_file = NULL;
    saida_file = NULL;
    for(itr = 1;itr < (unsigned int)argc;itr++)
    {
/* Instrucoes de uso */
        if( strcmp(argv[itr],"-a") == 0 || strcmp(argv[itr],"--ajuda") == 0 || 
            strcmp(argv[itr],"-h") == 0 || strcmp(argv[itr],"--help") == 0 )
        {
            if(rank == 0)
            {
                printf(" Uso: mpiexec -n [PROCESSOS] ./sm-rijndael [ARGUMENTO VALOR].\n");
                printf(" Encripta/Decripta um arquivo usando o algoritmo Rijndael(AES) extendido,\n");
                printf(" realizando um pre-processamento de blocos repetidos.\n");
                printf("  Argumentos opcionais:\n");
                printf("   -v,--verbose: Exibe mensagens de conclusao da operacao.\n");
                printf("   -j,--juntar: Concatena as tabelas de cada processo em um mestre.\n");
                printf("  Argumentos obrigatorios:\n");
                printf("   -op,--operacao: Informa se o objetivo da execucao eh encriptar ou decriptar.\n");
                printf("                    * Os valores possiveis sao: \'encriptar\' e \'decriptar\'.\n");
                printf("   -e,-i,--entrada,--input: Caminho e nome do arquivo a ser criptografado.\n");
                printf("   -s,-o,--saida,--output: Caminho e nome do arquivo resultante do processo de criptografia da entrada.\n");
                printf("   -c,-k,--chave,--key: Caminho e nome do arquivo contendo a chave.\n");
                printf("  O arquivo contendo a chave eh em formato binario de acordo com a seguinte especificacao:\n");
                printf("   - O primeiro byte deve conter o tamanho do bloco (em palavras de 4 bytes).\n");
                printf("      * O bloco pode possuir tamanho: 4, 5, 6, 7 ou 8.\n");
                printf("   - O segundo byte deve conter o tamanho da chave (em palavras de 4 bytes).\n");
                printf("      * Esta aplicacao aceita chaves com tamanho: 4, 5, 6, 7 ou 8.\n");
                printf("   - Os proximos 4*[tamanho da chave] bytes do arquivo sao os bytes componentes da chave, que\n");
                printf("     devem estar (obrigatoriamente) escritos no formato hexadecimal da linguagem C (0xff).\n");
                printf("   * Eh recomendavel o uso de um editor hexadecimal na construcao do arquivo chave.\n");
            }
            goto finalizando;
        }

/* Juntar: Concatena as tabelas de cada processo em um mestre */
        else
        if( strcmp(argv[itr],"-j") == 0 || strcmp(argv[itr],"--juntar") == 0)
        {
            juntar = 1;
        }

/* Verbose: exibir mensagens de finalizacao */
        else
        if( strcmp(argv[itr],"-v") == 0 || strcmp(argv[itr],"--verbose") == 0)
        {
            verbose = 1;
        }

/* Operacao a ser realizada */
        else
        if( strcmp(argv[itr],"-op") == 0 || strcmp(argv[itr],"--operacao") == 0 )
        {
            if( itr+1 < argc )
            {
                if( strcmp(argv[itr+1],"encriptar") == 0 )
                {
                    operacao = ENCRIPTAR;
                }
                else
                if( strcmp(argv[itr+1],"decriptar") == 0 )
                {
                    operacao = DECRIPTAR;
                }
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo com a chave */
        else
        if( strcmp(argv[itr],"-c") == 0 || strcmp(argv[itr],"--chave") == 0 || 
            strcmp(argv[itr],"-k") == 0 || strcmp(argv[itr],"--key") == 0 )
        {
            if(itr+1 < argc)
            {
                chave_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo de entrada */
        else
        if( strcmp(argv[itr],"-e") == 0 || strcmp(argv[itr],"--entrada") == 0 || 
            strcmp(argv[itr],"-i") == 0 || strcmp(argv[itr],"--input") == 0 )
        {
            if(itr+1 < argc)
            {
                entrada_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo de saida */
        else 
        if( strcmp(argv[itr],"-s") == 0 || strcmp(argv[itr],"--saida") == 0 || 
            strcmp(argv[itr],"-o") == 0 || strcmp(argv[itr],"--output") == 0 )
        {
            if(itr+1 < argc)
            {
                saida_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }
/* Erro desconhecido */
        else
        {
            if(rank == 0)
            {
                printf("Erro nos argumentos passados.\n");
            }
            goto help;
        }
    }
/* Fim da leitura dos argumentos */

    if( operacao == INDEFINIDA || chave_file == NULL || entrada_file == NULL || saida_file == NULL )
    {
        if(rank == 0)
        {
            if( operacao == INDEFINIDA )
                printf("A operacao a ser realizada eh invalida ou nao foi especificada.\n");
            if( chave_file == NULL )
                printf("Esta faltando especificar o arquivo com a chave.\n");
            if( entrada_file == NULL )
                printf("Esta faltando especificar o arquivo de entrada.\n");
            if( saida_file == NULL )
                printf("Esta faltando especificar o arquivo de saida.\n");
        }
        goto help;
    }
/* Fim do tratamento dos argumentos */

    if( MPI_File_open( MPI_COMM_WORLD, chave_file, MPI_MODE_RDONLY, MPI_INFO_NULL, &chave_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na abertura do arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,&Nb,1, MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura do tamanho de um bloco no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }
    if( Nb< 4 || Nb > 8 )
    {
        if( rank == 0 )
        {
            printf("Tamanho de bloco invalido no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,&Nk,1, MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura do tamanho da chave no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }
    if( Nk< 4 || Nk > 8 )
    {
        if( rank == 0 )
        {
            printf("Tamanho de chave invalido no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,chave,4*Nk,MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura da chave no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    MPI_File_close( &chave_handle );
    Nr = numero_rodadas(Nb,Nk);
    KeyExpansion(chave,Nb,Nk);

    if( MPI_File_open( MPI_COMM_WORLD, entrada_file, 
            MPI_MODE_RDONLY, 
            MPI_INFO_NULL, &entrada_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na abertura do arquivo de entrada (%s).\n",entrada_file);
        }
        goto help;
    }

    MPI_File_get_size(entrada_handle,&entrada_bytes);


    if( MPI_File_open( MPI_COMM_WORLD, saida_file, 
            MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_EXCL, 
            MPI_INFO_NULL, &saida_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na criacao do arquivo de saida (%s).\n",saida_file);
            printf("Uma possivel causa eh que o arquivo ja exista.\n");
        }
        goto help;
    }

    numero_blocos = ( entrada_bytes / (Nb*4) );
    blocos_processo = numero_blocos / worldsize;

    if( operacao == ENCRIPTAR || operacao == DECRIPTAR )
    {
        bloco_byte_inicio = 4*Nb*blocos_processo*rank;
        bloco_byte_fim = 4*Nb*blocos_processo*(rank+1);

        tabela = novaTabela(Nb*4);

        for( iterador = bloco_byte_inicio ; iterador < bloco_byte_fim ; iterador += (4*Nb) )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }

            novaOcorrenciaTabela(tabela,bloco,iterador);
        }
        
        iterador = 4*Nb*blocos_processo*worldsize + 4*Nb*rank;
        if( iterador < numero_blocos*4*Nb )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }

            novaOcorrenciaTabela(tabela,bloco,iterador);
        }
        else if( operacao == ENCRIPTAR  &&  iterador == numero_blocos*4*Nb )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }
            bloco[ 4*Nb - 1 ] = (octeto)(entrada_bytes - numero_blocos*4*Nb);
            novaOcorrenciaTabela(tabela,bloco,iterador);
        }


        if( juntar == 1 )
        {
            tabelaEmpacotada = (octeto*)malloc( entrada_bytes );
            if( rank == 0 ) /* Mestre que vai concatenar todas as arvores*/
            {
                for(proc=1;proc<worldsize;proc++)
                {
                    MPI_Recv( tabelaEmpacotada, entrada_bytes, MPI_BYTE, MPI_ANY_SOURCE, TAG_TABELA_EMPACOTADA, MPI_COMM_WORLD, &status );
                    desempacotarInserindo(tabelaEmpacotada,tabela);
                }
                
                tamanho_tabela = numeroBlocosTabela(tabela);

                no_proc = (tamanho_tabela / worldsize);
                no_resto = (tamanho_tabela % worldsize);
                
                tabela2 = novaTabela(Nb*4);
                for(proc=1;proc<worldsize;proc++)
                {
                    for(i=0;i<no_proc;i++)
                    {
                        soInsiraTabela(tabela2, popLastTabelaNode(tabela) );
                    }
                    if( no_resto > 1 )
                    {
                        soInsiraTabela(tabela2, popLastTabelaNode(tabela) );
                        no_resto--;
                    }
                    empacotarTabela(tabela2,tabelaEmpacotada);

                    MPI_Send(tabelaEmpacotada,numeroBytesTabela(tabela2), MPI_BYTE, proc, TAG_TABELA_EMPACOTADA_2, MPI_COMM_WORLD );

                    destruirArvore(tabela2->root);
                    tabela2->root = NULL;
                }
                destruirTabela(tabela2);
            }
            else
            {
                empacotarTabela(tabela,tabelaEmpacotada);
                MPI_Send(tabelaEmpacotada,numeroBytesTabela(tabela), MPI_BYTE, 0, TAG_TABELA_EMPACOTADA, MPI_COMM_WORLD );
                destruirArvore(tabela->root);
                tabela->root = NULL;

                MPI_Recv( tabelaEmpacotada, entrada_bytes, MPI_BYTE, 0, TAG_TABELA_EMPACOTADA_2, MPI_COMM_WORLD, &status );
                desempacotarInserindo(tabelaEmpacotada,tabela);
            }
            free(tabelaEmpacotada);
        }

        if( operacao == ENCRIPTAR )
            MPI_File_set_size(saida_handle,(MPI_Offset)( (numero_blocos+1)*(Nb*4) ) );
        else if( operacao == DECRIPTAR )
            MPI_File_set_size(saida_handle,entrada_bytes);

        tamanho_tabela = numeroBlocosTabela(tabela);
        for( i=0 ; i<tamanho_tabela ; i++ )
        {
            node = popLastTabelaNode(tabela);
//          memcpy (bloco,node->bloco,4*Nb);

            if( operacao == ENCRIPTAR )
                AES_encriptar_bloco(node->bloco,Nb,chave,Nr);
            else if( operacao == DECRIPTAR )
                AES_decriptar_bloco(node->bloco,Nb,chave,Nr);

            indice = node->ocorrencias;
            while( indice != NULL )
            {
                if( MPI_File_write_at(saida_handle,indice->indice,node->bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
                {
                    if( rank == 0 )
                    {
                        printf("Erro ao escrever no arquivo de saida (%s).\n",saida_file);
                    }
                    goto help;
                }
                indice = indice->next;
            }
            destruirArvore(node);
        }
        destruirTabela(tabela);

        if( operacao == DECRIPTAR )
        {
            MPI_Barrier( MPI_COMM_WORLD ); /*Barreira q impede q alguem leia antes do valor decriptografado ser escrito */

            if( MPI_File_read_at(saida_handle,entrada_bytes-1,bloco,1,MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao realizar leitura no arquivo de saida (%s).\n",saida_file);
                }
                goto help;
            }

            MPI_Barrier( MPI_COMM_WORLD ); /* Barreira q impede q alqum processo trunque o arquivo antes de outro processo ler*/

            MPI_File_set_size(saida_handle,entrada_bytes - 4*Nb + bloco[0]);
        }

        if( rank == 0 && verbose==1)
        {
            if( operacao == ENCRIPTAR )
                printf("A encriptacao do arquivo foi realizada com sucesso.\n");
            else if( operacao == DECRIPTAR )
                printf("A decriptacao do arquivo foi realizada com sucesso.\n");
        }
    }

    goto finalizando;

sempar:
    if( rank == 0 )
    {
        printf("Sem par correspondente para a opcao %s.\n",argv[itr]);
    }

help:
    if( rank == 0 )
    {
        printf("Use a opcao --help para melhor entendimento do uso da aplicacao.\n");
    }

finalizando:
    MPI_Finalize( );
    return 0;
}