Rijndael (from cryptolib)

Тема в разделе "WASM.CRYPTO", создана пользователем Prince, 16 июл 2008.

  1. Prince

    Prince New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2008
    Сообщения:
    71
    Вобщем просто разбирался с этим алгоритмом на примере исходника из приведенной в теме топика библиотеке
    Возможно ли такое, что в реализации присутствует ошибка?
    Вот эта функция
    Код (Text):
    1. aes_keystream *rijndael_setkey (const unsigned long *key, aes_keystream *ks)
    Вот этот код
    Код (Text):
    1.     for (i = 0; i < 56; i += 8)
    2.     {
    3.         t = ls_box (rotr32 (t, 8)) ^ rco_tab[i];
    4. ...
    И вобщем не могу понять, что за данные извлекаются из этой таблицы rco_tab, если ее размер задан как
    Код (Text):
    1. static unsigned long    rco_tab[ 10];
    Из-за этого aes_keystream для rinjdael заполняется как попало.

    Ругаться не нужно, если кто-то в курсе, что тут за проблема - подскажите.
     
  2. Prince

    Prince New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2008
    Сообщения:
    71
    Код (Text):
    1. static unsigned char    pow_tab[256];
    2. static unsigned char    log_tab[256];
    3. static unsigned char    sbx_tab[256];
    4. static unsigned char    isb_tab[256];
    5. static unsigned long    rco_tab[ 10];
    6. static unsigned long    ft_tab[4][256];
    7. static unsigned long    it_tab[4][256];
    8. static unsigned long    fl_tab[4][256];
    9. static unsigned long    il_tab[4][256];
    10.  
    11. #define ff_mult(a,b)    (((a) && (b)) ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
    12. #define byte(x, n)      (((x) >> (n << 3)) & 0xFF)
    13. #define f_rn(y,x,n,k)   (y->D[n] = ft_tab[0][byte(x->D[n],0)] ^ ft_tab[1][byte(x->D[(n + 1) & 3],1)] ^ ft_tab[2][byte(x->D[(n + 2) & 3],2)] ^ ft_tab[3][byte(x->D[(n + 3) & 3],3)] ^ k[n])
    14. #define f_rl(y,x,n,k)   (y->D[n] = fl_tab[0][byte(x->D[n],0)] ^ fl_tab[1][byte(x->D[(n + 1) & 3],1)] ^ fl_tab[2][byte(x->D[(n + 2) & 3],2)] ^ fl_tab[3][byte(x->D[(n + 3) & 3],3)] ^ k[n])
    15. #define i_rn(y,x,n,k)   (y->D[n] = it_tab[0][byte(x->D[n],0)] ^ it_tab[1][byte(x->D[(n + 3) & 3],1)] ^ it_tab[2][byte(x->D[(n + 2) & 3],2)] ^ it_tab[3][byte(x->D[(n + 1) & 3],3)] ^ k[n])
    16. #define i_rl(y,x,n,k)   (y->D[n] = il_tab[0][byte(x->D[n],0)] ^ il_tab[1][byte(x->D[(n + 3) & 3],1)] ^ il_tab[2][byte(x->D[(n + 2) & 3],2)] ^ il_tab[3][byte(x->D[(n + 1) & 3],3)] ^ k[n])
    17. #define ls_box(x)       (fl_tab[0][byte(x,0)] ^ fl_tab[1][byte(x,1)] ^ fl_tab[2][byte(x,2)] ^ fl_tab[3][byte(x,3)])
    18. #define star_x(x)       (((x) & 0x7F7F7F7F) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1B)
    19. #define imix_col(y,x)   (u = star_x(x), v = star_x(u), w = star_x(v), t = w ^ (x), (y) = u ^ v ^ w, (y) ^= rotr32 (u ^ t, 8) ^ rotr32 (v ^ t, 16) ^ rotr32 (t, 24))
    20. #define f_nround(y,x,k) (f_rn (y, x, 0, k), f_rn (y, x, 1, k), f_rn (y, x, 2, k), f_rn (y, x, 3, k), k += 4)
    21. #define f_lround(y,x,k) (f_rl (y, x, 0, k), f_rl (y, x, 1, k), f_rl (y, x, 2, k), f_rl (y, x, 3, k))
    22. #define i_nround(y,x,k) (i_rn (y, x, 0, k), i_rn (y, x, 1, k), i_rn (y, x, 2, k), i_rn (y, x, 3, k), k -= 4)
    23. #define i_lround(y,x,k) (i_rl (y, x, 0, k), i_rl (y, x, 1, k), i_rl (y, x, 2, k), i_rl (y, x, 3, k))
    24.  
    25. static void generate_rijndael_tables(void)
    26. {
    27.     unsigned long           i, t;
    28.     unsigned char           p, q;
    29.    
    30.     /* log and power tables for GF(2**8) finite field with */
    31.     /* 0x11B as modular polynomial - the simplest prmitive */
    32.     /* root is 0x11, used here to generate the tables      */
    33.    
    34.     for (i = 0, p = 1; i < 256; i++)
    35.     {
    36.         pow_tab[i] = (unsigned char) p; log_tab[p] = (unsigned char) i;
    37.         p = p ^ (p << 1) ^ (p & 0x80 ? 0x01B : 0);
    38.     }
    39.    
    40.     log_tab[1] = 0; p = 1;
    41.    
    42.     for (i = 0; i < 10; i++)
    43.     {
    44.         rco_tab[i] = p;
    45.         p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
    46.     }
    47.    
    48.     /* note that the affine byte transformation matrix in   */
    49.     /* rijndael specification is in big endian format with  */
    50.     /* bit 0 as the most significant bit. In the remainder  */
    51.     /* of the specification the bits are numbered from the  */
    52.     /* least significant end of a byte.                  */
    53.    
    54.     for (i = 0; i < 256; ++i)
    55.     {
    56.         p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p;
    57.         q = (q >> 7) | (q << 1); p ^= q;
    58.         q = (q >> 7) | (q << 1); p ^= q;
    59.         q = (q >> 7) | (q << 1); p ^= q;
    60.         q = (q >> 7) | (q << 1); p ^= q ^ 0x63;
    61.         sbx_tab[i] = (unsigned char) p; isb_tab[p] = (unsigned char) i;
    62.     }
    63.    
    64.     for (i = 0; i < 256; ++i)
    65.     {
    66.         fl_tab[0][i] = t = p = sbx_tab[i];
    67.         fl_tab[1][i] = rotl32 (t,  8);
    68.         fl_tab[2][i] = rotl32 (t, 16);
    69.         fl_tab[3][i] = rotl32 (t, 24);
    70.        
    71.         ft_tab[0][i] = t = ((unsigned long) ff_mult(2, p)) | ((unsigned long) p <<  8) | ((unsigned long) p << 16) | ((unsigned long) ff_mult(3, p) << 24);
    72.         ft_tab[1][i] = rotl32 (t,  8);
    73.         ft_tab[2][i] = rotl32 (t, 16);
    74.         ft_tab[3][i] = rotl32 (t, 24);
    75.        
    76.         il_tab[0][i] = t = p = isb_tab[i];
    77.         il_tab[1][i] = rotl32(t,  8);
    78.         il_tab[2][i] = rotl32(t, 16);
    79.         il_tab[3][i] = rotl32(t, 24);
    80.        
    81.         it_tab[0][i] = t = ((unsigned long) ff_mult (14, p)) | ((unsigned long) ff_mult (9, p) << 8) | ((unsigned long) ff_mult (13, p) << 16) | ((unsigned long) ff_mult (11, p) << 24);
    82.         it_tab[1][i] = rotl32(t,  8);
    83.         it_tab[2][i] = rotl32(t, 16);
    84.         it_tab[3][i] = rotl32(t, 24);
    85.     }
    86. }
    87.  
    88. aes_keystream *rijndael_setkey (const unsigned long *key, aes_keystream *ks)
    89. {
    90.     unsigned long           i, t, u, v, w;
    91.    
    92.     if (!pow_tab[0]) generate_rijndael_tables();
    93.    
    94.     for (i = 0; i < 8; i++) ks->un.rijndael.e_key[i] = t = lsf32 (key[i]);
    95.    
    96.     for (i = 0; i < 56; i += 8)
    97.     {
    98.         t = ls_box (rotr32 (t, 8)) ^ rco_tab[i]; t ^= ks->un.rijndael.e_key[i];
    99.         ks->un.rijndael.e_key[i +  8] = t;  t ^= ks->un.rijndael.e_key[i + 1];
    100.         ks->un.rijndael.e_key[i +  9] = t;  t ^= ks->un.rijndael.e_key[i + 2];
    101.         ks->un.rijndael.e_key[i + 10] = t;  t ^= ks->un.rijndael.e_key[i + 3];
    102.         ks->un.rijndael.e_key[i + 11] = t;  t  = ks->un.rijndael.e_key[i + 4] ^ ls_box (t);
    103.         ks->un.rijndael.e_key[i + 12] = t;  t ^= ks->un.rijndael.e_key[i + 5];
    104.         ks->un.rijndael.e_key[i + 13] = t;  t ^= ks->un.rijndael.e_key[i + 6];
    105.         ks->un.rijndael.e_key[i + 14] = t;  t ^= ks->un.rijndael.e_key[i + 7];
    106.         ks->un.rijndael.e_key[i + 15] = t;
    107.     }
    108.     memcpy (ks->un.rijndael.d_key, ks->un.rijndael.e_key, 16);
    109.    
    110.     for (i = 4; i < 56; i++) imix_col (ks->un.rijndael.d_key[i], ks->un.rijndael.e_key[i]);
    111.    
    112.     return ks;
    113. }
    114.  
    115. OCTET * rijndael_encrypt (OCTET one_block[2], const aes_keystream *ks)
    116. {
    117.     OCTET                   b0[2], b1[2];
    118.     const unsigned long     *kp = ks->un.rijndael.e_key + 4;
    119.    
    120.     b0->D[0] = lsf32 (one_block->D[0]) ^ ks->un.rijndael.e_key[0];
    121.     b0->D[1] = lsf32 (one_block->D[1]) ^ ks->un.rijndael.e_key[1];
    122.     b0->D[2] = lsf32 (one_block->D[2]) ^ ks->un.rijndael.e_key[2];
    123.     b0->D[3] = lsf32 (one_block->D[3]) ^ ks->un.rijndael.e_key[3];
    124.    
    125.     f_nround (b1, b0, kp); f_nround (b0, b1, kp);
    126.     f_nround (b1, b0, kp); f_nround (b0, b1, kp);
    127.     f_nround (b1, b0, kp); f_nround (b0, b1, kp);
    128.     f_nround (b1, b0, kp); f_nround (b0, b1, kp);
    129.     f_nround (b1, b0, kp); f_nround (b0, b1, kp);
    130.     f_nround (b1, b0, kp); f_nround (b0, b1, kp);
    131.     f_nround (b1, b0, kp); f_lround (b0, b1, kp);
    132.    
    133.     one_block->D[0] = lsf32 (b0->D[0]);
    134.     one_block->D[1] = lsf32 (b0->D[1]);
    135.     one_block->D[2] = lsf32 (b0->D[2]);
    136.     one_block->D[3] = lsf32 (b0->D[3]);
    137.    
    138.     return one_block;
    139. }
     
  3. Prince

    Prince New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2008
    Сообщения:
    71
  4. Ruptor

    Ruptor Marcos el Ruptor

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    167
    Адрес:
    Australia
    generate_rijndael_tables вызывал? его надо выполнять один раз на процесс.
     
  5. Ra_

    Ra_ New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2007
    Сообщения:
    289
  6. Prince

    Prince New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2008
    Сообщения:
    71
    Ruptor
    Да, конечно - таблицы в любом случае генерируются при вызове rijndael_setkey
    Факт, что обращение идет непонятно по каким индексам (ну мне например непонятно)
    Выходит, что вычисление раундовых ключей происходит или неверно, или неясно
    Код (Text):
    1.     for (i = 0; i < 56; i += 8)
    2.     {
    3.         t = ls_box (rotr32 (t, 8)) ^ rco_tab[i];
    4. ...
    Скорее всего индекс в данном случае нужно получать в виде = i/Nk (Nk - длина ключа в словах, 8 в данном случае или
    CIPHER_KEY_WORDS - дефайн из aes.h)
    Об этом речь идет и в спецификации
    Ruptor, хотелось бы, чтобы ты это прояснил, если будет время

    Ra_
    Нуу, я просто разбирался с алгоритмом по спецификации и взял для примера эту реализацию, но что-то тут не так :-/
     
  7. Ruptor

    Ruptor Marcos el Ruptor

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    167
    Адрес:
    Australia
    Совершенно верно. Там должно быть i/8. Исправлено. Спасибо!
     
  8. Prince

    Prince New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2008
    Сообщения:
    71
    Ruptor
    Тогда не ясно почему 10 элементов, ведь должно быть максимально 8 коэффициентов.
    Или не то что-то говорю?
     
  9. Ruptor

    Ruptor Marcos el Ruptor

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    167
    Адрес:
    Australia
    Prince это осталось от более расширенного кода который поддерживал 128 и 192 битовые ключи. всё верно, можно и до 8 сократить.

    моя библиотека принципиально направлена на уменьшение такого никчемного "разнообразия" как поддержка ключей разных длин в одной программе. меньше опций – меньше дыр. кому надо всё подряд – библиотек полно. я же буду продолжать отрезать ненужное и оставлять только всё необходимое и одного размера, как кирпич, вплоть до полной автоматизации всего процесса с минимальными исходниками максимальной чистоты и простоты. спасибо за помощь с этим багом!
     
  10. Ruptor

    Ruptor Marcos el Ruptor

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    167
    Адрес:
    Australia
    точнее до 7