Changeset 8a64320e in mainline for uspace/lib/crypto/crypto.c


Ignore:
Timestamp:
2015-04-23T23:40:14Z (10 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
dcba819
Parents:
09044cb
Message:

pre-merge coding style cleanup and code review

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/crypto/crypto.c

    r09044cb r8a64320e  
    2828
    2929/** @file crypto.c
    30  * 
     30 *
    3131 * Cryptographic functions library.
    3232 */
     
    3737#include <errno.h>
    3838#include <byteorder.h>
    39 
    4039#include "crypto.h"
    4140
    42 /* Hash function procedure definition. */
    43 typedef void (*HASH_FUNC)(uint32_t*, uint32_t*);
    44 
    45 /* Length of HMAC block. */
    46 #define HMAC_BLOCK_LENGTH 64
    47 
    48 /* Ceiling for UINT32. */
    49 #define ceil_uint32(val) (((val) - (uint32_t)(val)) > 0 ? \
    50         (uint32_t)((val) + 1) : (uint32_t)(val))
    51 
    52 /* Floor for UINT32. */
    53 #define floor_uint32(val) (((val) - (uint32_t)(val)) < 0 ? \
    54         (uint32_t)((val) - 1) : (uint32_t)(val))
    55 
    56 /* Pick value at specified index from array or zero if out of bounds. */
    57 #define get_at(input, size, i) (i < size ? input[i] : 0)
    58 
    59 /* Init values used in SHA1 and MD5 functions. */
     41/** Hash function procedure definition. */
     42typedef void (*hash_fnc_t)(uint32_t *, uint32_t *);
     43
     44/** Length of HMAC block. */
     45#define HMAC_BLOCK_LENGTH  64
     46
     47/** Ceiling for uint32_t. */
     48#define ceil_uint32(val) \
     49        (((val) - (uint32_t) (val)) > 0 ? \
     50        (uint32_t) ((val) + 1) : (uint32_t) (val))
     51
     52/** Floor for uint32_t. */
     53#define floor_uint32(val) \
     54        (((val) - (uint32_t) (val)) < 0 ? \
     55        (uint32_t) ((val) - 1) : (uint32_t) (val))
     56
     57/** Pick value at specified index from array or zero if out of bounds. */
     58#define get_at(input, size, i) \
     59        ((i) < (size) ? (input[i]) : 0)
     60
     61/** Init values used in SHA1 and MD5 functions. */
    6062static const uint32_t hash_init[] = {
    61         0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
     63        0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
    6264};
    6365
    64 /* Shift amount array for MD5 algorithm. */
     66/** Shift amount array for MD5 algorithm. */
    6567static const uint32_t md5_shift[] = {
    6668        7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,
     
    7072};
    7173
    72 /* Substitution box for MD5 algorithm. */
     74/** Substitution box for MD5 algorithm. */
    7375static const uint32_t md5_sbox[] = {
    7476        0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
     
    9092};
    9193
    92 /**
    93  * Working procedure of MD5 cryptographic hash function.
    94  *
    95  * @param h Working array with interim hash parts values.
     94/** Working procedure of MD5 cryptographic hash function.
     95 *
     96 * @param h         Working array with interim hash parts values.
    9697 * @param sched_arr Input array with scheduled values from input string.
     98 *
    9799 */
    98100static void md5_proc(uint32_t *h, uint32_t *sched_arr)
    99101{
    100102        uint32_t f, g, temp;
    101         uint32_t w[HASH_MD5/4];
    102        
    103         memcpy(w, h, (HASH_MD5/4) * sizeof(uint32_t));
    104        
    105         for(size_t k = 0; k < 64; k++) {
    106                 if(k < 16) {
     103        uint32_t w[HASH_MD5 / 4];
     104       
     105        memcpy(w, h, (HASH_MD5 / 4) * sizeof(uint32_t));
     106       
     107        for (size_t k = 0; k < 64; k++) {
     108                if (k < 16) {
    107109                        f = (w[1] & w[2]) | (~w[1] & w[3]);
    108110                        g = k;
    109                 } else if(k >= 16 && k < 32) {
     111                } else if ((k >= 16) && (k < 32)) {
    110112                        f = (w[1] & w[3]) | (w[2] & ~w[3]);
    111                         g = (5*k + 1) % 16;
    112                 } else if(k >= 32 && k < 48) {
     113                        g = (5 * k + 1) % 16;
     114                } else if ((k >= 32) && (k < 48)) {
    113115                        f = w[1] ^ w[2] ^ w[3];
    114                         g = (3*k + 5) % 16;
     116                        g = (3 * k + 5) % 16;
    115117                } else {
    116118                        f = w[2] ^ (w[1] | ~w[3]);
    117                         g = 7*k % 16;
     119                        g = 7 * k % 16;
    118120                }
     121               
    119122                temp = w[3];
    120123                w[3] = w[2];
    121124                w[2] = w[1];
    122                 w[1] += rotl_uint32(w[0] + f + md5_sbox[k] + 
    123                         uint32_t_byteorder_swap(sched_arr[g]), 
    124                         md5_shift[k]);
     125                w[1] += rotl_uint32(w[0] + f + md5_sbox[k] +
     126                    uint32_t_byteorder_swap(sched_arr[g]),
     127                    md5_shift[k]);
    125128                w[0] = temp;
    126129        }
    127130       
    128         for(uint8_t k = 0; k < HASH_MD5/4; k++)
     131        for (uint8_t k = 0; k < HASH_MD5 / 4; k++)
    129132                h[k] += w[k];
    130133}
    131134
    132 /**
    133  * Working procedure of SHA-1 cryptographic hash function.
    134  *
    135  * @param h Working array with interim hash parts values.
     135/** Working procedure of SHA-1 cryptographic hash function.
     136 *
     137 * @param h         Working array with interim hash parts values.
    136138 * @param sched_arr Input array with scheduled values from input string.
     139 *
    137140 */
    138141static void sha1_proc(uint32_t *h, uint32_t *sched_arr)
    139142{
    140143        uint32_t f, cf, temp;
    141         uint32_t w[HASH_SHA1/4];
    142        
    143         for(size_t k = 16; k < 80; k++) {
     144        uint32_t w[HASH_SHA1 / 4];
     145       
     146        for (size_t k = 16; k < 80; k++) {
    144147                sched_arr[k] = rotl_uint32(
    145                         sched_arr[k-3] ^
    146                         sched_arr[k-8] ^
    147                         sched_arr[k-14] ^
    148                         sched_arr[k-16],
    149                         1);
    150         }
    151 
    152         memcpy(w, h, (HASH_SHA1/4) * sizeof(uint32_t));
    153        
    154         for(size_t k = 0; k < 80; k++) {
    155                 if(k < 20) {
     148                    sched_arr[k-3] ^
     149                    sched_arr[k-8] ^
     150                    sched_arr[k-14] ^
     151                    sched_arr[k-16],
     152                    1);
     153        }
     154       
     155        memcpy(w, h, (HASH_SHA1 / 4) * sizeof(uint32_t));
     156       
     157        for (size_t k = 0; k < 80; k++) {
     158                if (k < 20) {
    156159                        f = (w[1] & w[2]) | (~w[1] & w[3]);
    157160                        cf = 0x5A827999;
    158                 } else if(k >= 20 && k < 40) {
     161                } else if ((k >= 20) && (k < 40)) {
    159162                        f = w[1] ^ w[2] ^ w[3];
    160                         cf = 0x6ED9EBA1;
    161                 } else if(k >= 40 && k < 60) {
     163                        cf = 0x6ed9eba1;
     164                } else if ((k >= 40) && (k < 60)) {
    162165                        f = (w[1] & w[2]) | (w[1] & w[3]) | (w[2] & w[3]);
    163                         cf = 0x8F1BBCDC;
     166                        cf = 0x8f1bbcdc;
    164167                } else {
    165168                        f = w[1] ^ w[2] ^ w[3];
    166                         cf = 0xCA62C1D6;
     169                        cf = 0xca62c1d6;
    167170                }
    168 
     171               
    169172                temp = rotl_uint32(w[0], 5) + f + w[4] + cf + sched_arr[k];
    170 
     173               
    171174                w[4] = w[3];
    172175                w[3] = w[2];
     
    175178                w[0] = temp;
    176179        }
    177 
    178         for(uint8_t k = 0; k < HASH_SHA1/4; k++)
     180       
     181        for (uint8_t k = 0; k < HASH_SHA1 / 4; k++)
    179182                h[k] += w[k];
    180183}
    181184
    182 /**
    183  * Create hash based on selected algorithm.
    184  *
    185  * @param input Input message byte sequence.
     185/** Create hash based on selected algorithm.
     186 *
     187 * @param input      Input message byte sequence.
    186188 * @param input_size Size of message sequence.
    187  * @param output Result hash byte sequence.
    188  * @param hash_sel Hash function selector.
    189  *
    190  * @return EINVAL when input not specified, ENOMEM when pointer for
    191  * output hash result is not allocated, otherwise EOK.
     189 * @param output     Result hash byte sequence.
     190 * @param hash_sel   Hash function selector.
     191 *
     192 * @return EINVAL when input not specified,
     193 *         ENOMEM when pointer for output hash result
     194 *         is not allocated, otherwise EOK.
     195 *
    192196 */
    193197int create_hash(uint8_t *input, size_t input_size, uint8_t *output,
    194         hash_func_t hash_sel)
    195 {
    196         if(!input)
     198    hash_func_t hash_sel)
     199{
     200        if (!input)
    197201                return EINVAL;
    198202       
    199         if(!output)
     203        if (!output)
    200204                return ENOMEM;
    201205       
    202         HASH_FUNC hash_func = (hash_sel == HASH_MD5) ? md5_proc : sha1_proc;
     206        hash_fnc_t hash_func = (hash_sel == HASH_MD5) ? md5_proc : sha1_proc;
    203207       
    204208        /* Prepare scheduled input. */
     
    207211        work_input[input_size] = 0x80;
    208212       
    209         size_t blocks = ceil_uint32((((double)input_size + 1) / 4 + 2) / 16);
     213        // FIXME: double?
     214        size_t blocks = ceil_uint32((((double) input_size + 1) / 4 + 2) / 16);
    210215        uint32_t work_arr[blocks * 16];
    211         for(size_t i = 0; i < blocks; i++) {
    212                 for(size_t j = 0; j < 16; j++) {
    213                         work_arr[i*16 + j] = 
    214                         (get_at(work_input, input_size+1, i*64+j*4) << 24) |
    215                         (get_at(work_input, input_size+1, i*64+j*4+1) << 16) |
    216                         (get_at(work_input, input_size+1, i*64+j*4+2) << 8) |
    217                         get_at(work_input, input_size+1, i*64+j*4+3);
     216        for (size_t i = 0; i < blocks; i++) {
     217                for (size_t j = 0; j < 16; j++) {
     218                        work_arr[i*16 + j] =
     219                            (get_at(work_input, input_size + 1, i * 64 + j * 4) << 24) |
     220                            (get_at(work_input, input_size + 1, i * 64 + j * 4 + 1) << 16) |
     221                            (get_at(work_input, input_size + 1, i * 64 + j * 4 + 2) << 8) |
     222                            get_at(work_input, input_size + 1, i * 64 + j * 4 + 3);
    218223                }
    219224        }
    220225       
    221         uint64_t bits_size = (uint64_t)(input_size * 8);
    222         if(hash_sel == HASH_MD5)
     226        uint64_t bits_size = (uint64_t) (input_size * 8);
     227        if (hash_sel == HASH_MD5)
    223228                bits_size = uint64_t_byteorder_swap(bits_size);
    224229       
    225230        work_arr[(blocks - 1) * 16 + 14] = bits_size >> 32;
    226         work_arr[(blocks - 1) * 16 + 15] = bits_size & 0xFFFFFFFF;
     231        work_arr[(blocks - 1) * 16 + 15] = bits_size & 0xffffffff;
    227232       
    228233        /* Hash computation. */
    229         uint32_t h[hash_sel/4];
    230         memcpy(h, hash_init, (hash_sel/4) * sizeof(uint32_t));
     234        uint32_t h[hash_sel / 4];
     235        memcpy(h, hash_init, (hash_sel / 4) * sizeof(uint32_t));
    231236        uint32_t sched_arr[80];
    232         for(size_t i = 0; i < blocks; i++) {
    233                 for(size_t k = 0; k < 16; k++) {
    234                         sched_arr[k] = work_arr[i*16 + k];
    235                 }
     237        for (size_t i = 0; i < blocks; i++) {
     238                for (size_t k = 0; k < 16; k++)
     239                        sched_arr[k] = work_arr[i * 16 + k];
    236240               
    237241                hash_func(h, sched_arr);
     
    239243       
    240244        /* Copy hash parts into final result. */
    241         for(size_t i = 0; i < hash_sel/4; i++) {
    242                 if(hash_sel == HASH_SHA1)
     245        for (size_t i = 0; i < hash_sel / 4; i++) {
     246                if (hash_sel == HASH_SHA1)
    243247                        h[i] = uint32_t_byteorder_swap(h[i]);
    244                 memcpy(output + i*sizeof(uint32_t), &h[i], sizeof(uint32_t));
     248               
     249                memcpy(output + i * sizeof(uint32_t), &h[i], sizeof(uint32_t));
    245250        }
    246251       
     
    248253}
    249254
    250 /**
    251  * Hash-based message authentication code.
    252  *
    253  * @param key Cryptographic key sequence.
     255/** Hash-based message authentication code.
     256 *
     257 * @param key      Cryptographic key sequence.
    254258 * @param key_size Size of key sequence.
    255  * @param msg Message sequence.
     259 * @param msg      Message sequence.
    256260 * @param msg_size Size of message sequence.
    257  * @param hash Output parameter for result hash.
     261 * @param hash     Output parameter for result hash.
    258262 * @param hash_sel Hash function selector.
    259  *
    260  * @return EINVAL when key or message not specified, ENOMEM when pointer for
    261  * output hash result is not allocated, otherwise EOK.
     263 *
     264 * @return EINVAL when key or message not specified,
     265 *         ENOMEM when pointer for output hash result
     266 *         is not allocated, otherwise EOK.
     267 *
    262268 */
    263269int hmac(uint8_t *key, size_t key_size, uint8_t *msg, size_t msg_size,
    264         uint8_t *hash, hash_func_t hash_sel)
    265 {
    266         if(!key || !msg)
     270    uint8_t *hash, hash_func_t hash_sel)
     271{
     272        if ((!key) || (!msg))
    267273                return EINVAL;
    268274       
    269         if(!hash)
     275        if (!hash)
    270276                return ENOMEM;
    271277       
     
    276282        memset(work_key, 0, HMAC_BLOCK_LENGTH);
    277283       
    278         if(key_size > HMAC_BLOCK_LENGTH) {
     284        if(key_size > HMAC_BLOCK_LENGTH)
    279285                create_hash(key, key_size, work_key, hash_sel);
    280         } else {
     286        else
    281287                memcpy(work_key, key, key_size);
    282         }
    283        
    284         for(size_t i = 0; i < HMAC_BLOCK_LENGTH; i++) {
    285                 o_key_pad[i] = work_key[i] ^ 0x5C;
     288       
     289        for (size_t i = 0; i < HMAC_BLOCK_LENGTH; i++) {
     290                o_key_pad[i] = work_key[i] ^ 0x5c;
    286291                i_key_pad[i] = work_key[i] ^ 0x36;
    287292        }
     
    291296        memcpy(temp_work + HMAC_BLOCK_LENGTH, msg, msg_size);
    292297       
    293         create_hash(temp_work, HMAC_BLOCK_LENGTH + msg_size, temp_hash, 
    294                 hash_sel);
     298        create_hash(temp_work, HMAC_BLOCK_LENGTH + msg_size, temp_hash,
     299            hash_sel);
    295300       
    296301        memcpy(temp_work, o_key_pad, HMAC_BLOCK_LENGTH);
     
    302307}
    303308
    304 /**
    305  * Password-Based Key Derivation Function 2 as defined in RFC 2898,
    306  * using HMAC-SHA1 with 4096 iterations and 32 bytes key result used
    307  * for WPA/WPA2.
    308  * 
    309  * @param pass Password sequence.
     309/** Password-Based Key Derivation Function 2.
     310 *
     311 * As defined in RFC 2898, using HMAC-SHA1 with 4096 iterations
     312 * and 32 bytes key result used for WPA/WPA2.
     313 *
     314 * @param pass      Password sequence.
    310315 * @param pass_size Password sequence length.
    311  * @param salt Salt sequence to be used with password.
     316 * @param salt      Salt sequence to be used with password.
    312317 * @param salt_size Salt sequence length.
    313  * @param hash Output parameter for result hash (32 byte value).
    314  *
    315  * @return EINVAL when pass or salt not specified, ENOMEM when pointer for
    316  * output hash result is not allocated, otherwise EOK.
    317  */
    318 int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size,
    319         uint8_t *hash)
    320 {
    321         if(!pass || !salt)
     318 * @param hash      Output parameter for result hash (32 byte value).
     319 *
     320 * @return EINVAL when pass or salt not specified,
     321 *         ENOMEM when pointer for output hash result
     322 *         is not allocated, otherwise EOK.
     323 *
     324 */
     325int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size,
     326    uint8_t *hash)
     327{
     328        if ((!pass) || (!salt))
    322329                return EINVAL;
    323330       
    324         if(!hash)
     331        if (!hash)
    325332                return ENOMEM;
    326333       
     
    330337        uint8_t temp_hmac[HASH_SHA1];
    331338        uint8_t xor_hmac[HASH_SHA1];
    332         uint8_t temp_hash[HASH_SHA1*2];
    333        
    334         for(size_t i = 0; i < 2; i++) {
    335                 uint32_t be_i = host2uint32_t_be(i+1);
     339        uint8_t temp_hash[HASH_SHA1 * 2];
     340       
     341        for (size_t i = 0; i < 2; i++) {
     342                uint32_t be_i = host2uint32_t_be(i + 1);
     343               
    336344                memcpy(work_salt + salt_size, &be_i, 4);
    337345                hmac(pass, pass_size, work_salt, salt_size + 4,
    338                         work_hmac, HASH_SHA1);
     346                    work_hmac, HASH_SHA1);
    339347                memcpy(xor_hmac, work_hmac, HASH_SHA1);
    340348               
    341                 for(size_t k = 1; k < 4096; k++) {
     349                for (size_t k = 1; k < 4096; k++) {
    342350                        memcpy(temp_hmac, work_hmac, HASH_SHA1);
    343                         hmac(pass, pass_size, temp_hmac, HASH_SHA1,
    344                                 work_hmac, HASH_SHA1);
    345                         for(size_t t = 0; t < HASH_SHA1; t++) {
     351                        hmac(pass, pass_size, temp_hmac, HASH_SHA1,
     352                            work_hmac, HASH_SHA1);
     353                       
     354                        for (size_t t = 0; t < HASH_SHA1; t++)
    346355                                xor_hmac[t] ^= work_hmac[t];
    347                         }
    348356                }
    349                 memcpy(temp_hash + i*HASH_SHA1, xor_hmac, HASH_SHA1);
     357               
     358                memcpy(temp_hash + i * HASH_SHA1, xor_hmac, HASH_SHA1);
    350359        }
    351360       
Note: See TracChangeset for help on using the changeset viewer.