0

在 libgcrypt 共享库中,在 AES 加密/解密操作期间访问查找表。在 AES 加密的情况下,1KB 查找表(定义为共享库中的静态 const u32 encT),在 AES 解密的情况下,1KB + 256 字节查找表(定义为

static const struct
{
  u32 T[256];
  byte inv_sbox[256];
} dec_tables inside shared library) are used.

作为共享库的静态成员,encT 和 dec_tables 将放置在哪里?在代码部分或任何其他部分?

当我用 nm 命令检查时,它显示 r ,表示只读。

nm /usr/local/lib/libgcrypt.so | grep encT
00091ae0 r encT

nm /usr/local/lib/libgcrypt.so | grep dec_tables
000915e0 r dec_tables

对于共享库,只读部分和代码部分是否相同?

我制作了一个示例程序来执行 AES 解密,并了解执行 AES 解密的程序的控制流程是什么。

gcryError = gcry_cipher_decrypt(
    gcryCipherHd, // gcry_cipher_hd_t
    dec_out,    // void *
    txtLength,    // size_t
    enc_out,    // const void *
    txtLength);   // size_t

这是我发现的,

 gcry_cipher_decrypt (visibility.c ) -->
 _gcry_cipher_decrypt (cipher.c) -->
 static cipher_decrypt (cipher.c) --> 
 static  do_ecb_decrypt  (cipher.c) --> 
 static do_ecb_crypt  (cipher.c) --> 
 static do_decrypt  (rijndael.c) --> 
 static do_decrypt_fn  (rijndael.c) 

在内部,do_decrypt_fn 函数最终解密操作是通过访问 dec_tables.T 和 dec_tables.inv_sbox 来执行的。

     // few lines are added for reference
static unsigned int
do_decrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b,
               const unsigned char *a)
{
      sb[3] ^= rol(decT[(byte)(sa[3] >> (0 * 8))], (0 * 8));
      sa[0] ^= rol(decT[(byte)(sa[3] >> (1 * 8))], (1 * 8));
      sa[1] ^= rol(decT[(byte)(sa[3] >> (2 * 8))], (2 * 8));
      sa[2] ^= rol(decT[(byte)(sa[3] >> (3 * 8))], (3 * 8));
      sa[3] = rk[1][3] ^ sb[3];

      /* Last round is special. */
      sb[0] = inv_sbox[(byte)(sa[0] >> (0 * 8))] << (0 * 8);
      sb[1] = inv_sbox[(byte)(sa[0] >> (1 * 8))] << (1 * 8);
      sb[2] = inv_sbox[(byte)(sa[0] >> (2 * 8))] << (2 * 8);
      sb[3] = inv_sbox[(byte)(sa[0] >> (3 * 8))] << (3 * 8);
      sa[0] = sb[0] ^ rk[0][0];

这里,dec_tables 定义在 rijndael-tables.h 中,这个头文件包含在 rijndael.c 文件中。

     static const struct
    {
      u32 T[256];
      byte inv_sbox[256];
    } dec_tables =
      {
        {
          0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a,
          0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
          ...},
           {
          0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
          0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
          ...}


#define decT dec_tables.T
#define inv_sbox dec_tables.inv_sbox   

这是我对你的问题。

  1. 作为静态类型,所有这些静态函数和静态数据 dec_tables 在共享库模块之外都是不可见的。那么它们是如何定位以用于解密的呢?
  2. 我认为 encT 和 dec_tables 的这个 OFFSET 被某些函数或在某些计算中用来定位 dec_tables 以执行 AES 解密。 我对吗 ?

  3. 谁能解释使用 readelf/objdump/nm 或其他方式,共享库如何使用这些 OFFSET 来定位用于 AES 加密/解密的静态数据(encT/dec_tables)?

或者

  1. 这些 OFFSET 在任何意义上对定位 encT/dec_tables 静态数据有用吗?

我不知道 GOT 或 PLT 如何与 OFFSET 一起使用。有没有办法使用这些关于 GOT/PLT 的 OFFSET 来定位这些静态数据?

我正在使用 Ubuntu 16.06,gcc-4.9。

任何解决上述疑惑的链接/示例程序都会有很大帮助。提前致谢。

4

0 回答 0