aboutsummaryrefslogblamecommitdiffstatshomepage
path: root/src/aes.c
blob: 0aded1a82fdc66557972b52da4a9b1688b2b3bab (plain) (tree)
1
2
3
4
5
6
7
8
9





                                                             
 
                    
 
                   
                  
                   
 



                                    
 
                

                  
                    
                                                           
                      
                                                             

                            
 
                                                  
                                              
 
                                             
                                          

                   
                       

 



                                              
 
                

                  
                    
                                                           
                      
                                                             

                            
 
                                                    
                                              
 
                                            
     


                                                  
     

                   
                       

 


                                   
 

                  
                      
                                                             
 

                                    
 
                                                                          
                  
 

                            

 


                                             
 

                  
                      
                                                             
 

                                    
 
                                                                                    
                  
 



                          

                                   
                    
                                  




                     
                                                            
                    
                                                           

                             



                                                  
     

                          
                                                    
                                                                        
                                        
                    

     

                                             

 



                                     
 



                    
                                                           
                    
                                                           



                                                  
                                                




                                             
                       

 



                                     
 
                
                
 
                    
                                                           
                    
                                                           

                            
 

                                                      
                                                   



                                                 
 
     
                                                      
                                                   


                                                


                   
                       

 



                                     
 
                
                
 
                    
                                                           
                    
                                                           

                            
 

                                                      
                                                   



                                                 
 
     
                                                      
                                                   


                                                 


                   
                       

 


                                    
 
                                                       

 


                                    
 
                
 
                    
                                                           
 

                                    
 
                                                                         



                            

 


                                    
 
                
 
                    
                                                           
 

                                    
 
                                                                         



                            

 

                                    
                    
                                  
 
                                                             

 

                                    
                    
                                  
 
                 

                
                     
                                                            
                    
                                                           

                             
 
     





                                                      
                                                        
                                                                            
                                            
                        

         
                                                    

     
     





                                                      
                                                        
                                                                            
                                            
                        


                                   
                                                    

     
                       

 

                                    
                    
                                  
 
                 

                
                     
                                                            
                    
                                                           

                             
 
     





                                                      
                                                        
                                                                            
                                            
                        

         
                                                    

     
     





                                                      
                                                        
                                                                            
                                            
                        

         
                                                    

     
                       
 
/*
 * Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com>
 * This file is part of the "AES tools" project.
 * For details, see https://github.com/egor-tensin/aes-tools.
 * Distributed under the MIT License.
 */

#include <aes/all.h>

#include <assert.h>
#include <stdio.h>
#include <string.h>

AES_StatusCode aes_AES_format_block(
    AES_AES_BlockString* str,
    const AES_AES_Block* block,
    AES_ErrorDetails* err_details)
{
    assert(str);
    assert(block);

    if (str == NULL)
        return aes_error_null_argument(err_details, "str");
    if (block == NULL)
        return aes_error_null_argument(err_details, "block");

    char* cursor = str->str;

    __declspec(align(16)) unsigned char bytes[16];
    aes_store_block128_aligned(bytes, *block);

    for (int i = 0; i < 16; ++i, cursor += 2)
        sprintf(cursor, "%02x", bytes[i]);

    *cursor = '\0';
    return AES_SUCCESS;
}

AES_StatusCode aes_AES_format_block_as_matrix(
    AES_AES_BlockMatrixString* str,
    const AES_AES_Block* block,
    AES_ErrorDetails* err_details)
{
    assert(str);
    assert(block);

    if (str == NULL)
        return aes_error_null_argument(err_details, "str");
    if (block == NULL)
        return aes_error_null_argument(err_details, "block");

    char* cursor = str->str;

    __declspec(align(16)) unsigned char bytes[4][4];
    aes_store_block128_aligned(bytes, *block);

    for (int i = 0; i < 4; ++i, cursor += 3)
    {
        for (int j = 0; j < 3; ++j, cursor += 3)
            sprintf(cursor, "%02x ", bytes[j][i]);
        sprintf(cursor, "%02x\n", bytes[3][i]);
    }

    *cursor = '\0';
    return AES_SUCCESS;
}

AES_StatusCode aes_AES_print_block(
    const AES_AES_Block* block,
    AES_ErrorDetails* err_details)
{
    assert(block);

    if (block == NULL)
        return aes_error_null_argument(err_details, "block");

    AES_StatusCode ec = AES_SUCCESS;
    AES_AES_BlockString str;

    if (aes_is_error(ec = aes_AES_format_block(&str, block, err_details)))
        return ec;

    printf("%s\n", str.str);
    return ec;
}

AES_StatusCode aes_AES_print_block_as_matrix(
    const AES_AES_Block* block,
    AES_ErrorDetails* err_details)
{
    assert(block);

    if (block == NULL)
        return aes_error_null_argument(err_details, "block");

    AES_StatusCode ec = AES_SUCCESS;
    AES_AES_BlockMatrixString str;

    if (aes_is_error(ec = aes_AES_format_block_as_matrix(&str, block, err_details)))
        return ec;

    printf("%s", str.str);
    return ec;
}

AES_StatusCode aes_AES_parse_block(
    AES_AES_Block* dest,
    const char* src,
    AES_ErrorDetails* err_details)
{
    assert(dest);
    assert(src);

    if (dest == NULL)
        return aes_error_null_argument(err_details, "dest");
    if (src == NULL)
        return aes_error_null_argument(err_details, "src");

    const char* cursor = src;

    __declspec(align(16)) unsigned char bytes[16];

    for (int i = 0; i < 16; ++i)
    {
        int n;
        unsigned int byte;
        if (sscanf(cursor, "%2x%n", &byte, &n) != 1)
            return aes_error_parse(err_details, src, "a 128-bit block");
        bytes[i] = (unsigned char) byte;
        cursor += n;
    }

    *dest = aes_load_block128_aligned(bytes);
    return AES_SUCCESS;
}

AES_StatusCode aes_AES128_format_key(
    AES_AES128_KeyString* str,
    const AES_AES128_Key* key,
    AES_ErrorDetails* err_details)
{
    assert(str);
    assert(key);

    if (str == NULL)
        return aes_error_null_argument(err_details, "str");
    if (key == NULL)
        return aes_error_null_argument(err_details, "key");

    char* cursor = str->str;

    __declspec(align(16)) unsigned char bytes[16];
    aes_store_block128_aligned(bytes, key->key);

    for (int i = 0; i < 16; ++i, cursor += 2)
        sprintf(cursor, "%02x", bytes[i]);

    *cursor = '\0';
    return AES_SUCCESS;
}

AES_StatusCode aes_AES192_format_key(
    AES_AES192_KeyString* str,
    const AES_AES192_Key* key,
    AES_ErrorDetails* err_details)
{
    assert(str);
    assert(key);

    if (str == NULL)
        return aes_error_null_argument(err_details, "str");
    if (key == NULL)
        return aes_error_null_argument(err_details, "key");

    char* cursor = str->str;

    {
        __declspec(align(16)) unsigned char bytes[16];
        aes_store_block128_aligned(bytes, key->lo);

        for (int i = 0; i < 16; ++i, cursor += 2)
            sprintf(cursor, "%02x", bytes[i]);
    }

    {
        __declspec(align(16)) unsigned char bytes[16];
        aes_store_block128_aligned(bytes, key->hi);

        for (int i = 0; i < 8; ++i, cursor += 2)
            sprintf(cursor, "%02x", bytes[i]);
    }

    *cursor = '\0';
    return AES_SUCCESS;
}

AES_StatusCode aes_AES256_format_key(
    AES_AES256_KeyString* str,
    const AES_AES256_Key* key,
    AES_ErrorDetails* err_details)
{
    assert(str);
    assert(key);

    if (str == NULL)
        return aes_error_null_argument(err_details, "str");
    if (key == NULL)
        return aes_error_null_argument(err_details, "key");

    char* cursor = str->str;

    {
        __declspec(align(16)) unsigned char bytes[16];
        aes_store_block128_aligned(bytes, key->lo);

        for (int i = 0; i < 16; ++i, cursor += 2)
            sprintf(cursor, "%02x", bytes[i]);
    }

    {
        __declspec(align(16)) unsigned char bytes[16];
        aes_store_block128_aligned(bytes, key->hi);

        for (int i = 0; i < 16; ++i, cursor += 2)
            sprintf(cursor, "%02x", bytes[i]);
    }

    *cursor = '\0';
    return AES_SUCCESS;
}

AES_StatusCode aes_AES128_print_key(
    const AES_AES128_Key* key,
    AES_ErrorDetails* err_details)
{
    return aes_AES_print_block(&key->key, err_details);
}

AES_StatusCode aes_AES192_print_key(
    const AES_AES192_Key* key,
    AES_ErrorDetails* err_details)
{
    assert(key);

    if (key == NULL)
        return aes_error_null_argument(err_details, "key");

    AES_StatusCode ec = AES_SUCCESS;
    AES_AES192_KeyString str;

    if (aes_is_error(ec = aes_AES192_format_key(&str, key, err_details)))
        return ec;

    printf("%s\n", str.str);
    return ec;
}

AES_StatusCode aes_AES256_print_key(
    const AES_AES256_Key* key,
    AES_ErrorDetails* err_details)
{
    assert(key);

    if (key == NULL)
        return aes_error_null_argument(err_details, "key");

    AES_StatusCode ec = AES_SUCCESS;
    AES_AES256_KeyString str;

    if (aes_is_error(ec = aes_AES256_format_key(&str, key, err_details)))
        return ec;

    printf("%s\n", str.str);
    return ec;
}

AES_StatusCode aes_AES128_parse_key(
    AES_AES128_Key* dest,
    const char* src,
    AES_ErrorDetails* err_details)
{
    return aes_AES_parse_block(&dest->key, src, err_details);
}

AES_StatusCode aes_AES192_parse_key(
    AES_AES192_Key* dest,
    const char* src,
    AES_ErrorDetails* err_details)
{
    assert(dest);
    assert(src);

    if (dest == NULL)
        return aes_error_null_argument(err_details, "dest");
    if (src == NULL)
        return aes_error_null_argument(err_details, "src");

    const char* cursor = src;

    {
        __declspec(align(16)) unsigned char bytes[16];

        for (int i = 0; i < 16; ++i)
        {
            int n;
            unsigned int byte;
            if (sscanf(cursor, "%2x%n", &byte, &n) != 1)
                return aes_error_parse(err_details, src, "a 192-bit block");
            bytes[i] = (unsigned char) byte;
            cursor += n;
        }

        dest->lo = aes_load_block128_aligned(bytes);
    }

    {
        __declspec(align(16)) unsigned char bytes[16];

        for (int i = 0; i < 8; ++i)
        {
            int n;
            unsigned int byte;
            if (sscanf(cursor, "%2x%n", &byte, &n) != 1)
                return aes_error_parse(err_details, src, "a 192-bit block");
            bytes[i] = (unsigned char) byte;
            cursor += n;
        }

        memset(bytes + 8, 0x00, 8);
        dest->hi = aes_load_block128_aligned(bytes);
    }

    return AES_SUCCESS;
}

AES_StatusCode aes_AES256_parse_key(
    AES_AES256_Key* dest,
    const char* src,
    AES_ErrorDetails* err_details)
{
    assert(dest);
    assert(src);

    if (dest == NULL)
        return aes_error_null_argument(err_details, "dest");
    if (src == NULL)
        return aes_error_null_argument(err_details, "src");

    const char* cursor = src;

    {
        __declspec(align(16)) unsigned char bytes[16];

        for (int i = 0; i < 16; ++i)
        {
            int n;
            unsigned int byte;
            if (sscanf(cursor, "%2x%n", &byte, &n) != 1)
                return aes_error_parse(err_details, src, "a 256-bit block");
            bytes[i] = (unsigned char) byte;
            cursor += n;
        }

        dest->lo = aes_load_block128_aligned(bytes);
    }

    {
        __declspec(align(16)) unsigned char bytes[16];

        for (int i = 0; i < 16; ++i)
        {
            int n;
            unsigned int byte;
            if (sscanf(cursor, "%2x%n", &byte, &n) != 1)
                return aes_error_parse(err_details, src, "a 256-bit block");
            bytes[i] = (unsigned char) byte;
            cursor += n;
        }

        dest->hi = aes_load_block128_aligned(bytes);
    }

    return AES_SUCCESS;
}