via_ace.h

来自「AES高级加密标准的C代码」· C头文件 代码 · 共 497 行 · 第 1/2 页

H
497
字号
}

static __inline volatile  void via_cfb_op7(
        const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
{   __asm
    {
        NEH_REKEY
        mov     ebx, (k)
        mov     edx, (c)
        mov     esi, (s)
        mov     edi, (d)
        mov     ecx, (l)
        mov     eax, (v)
        NEH_CFB
        mov     esi, eax
        mov     edi, (w)
        movsd
        movsd
        movsd
        movsd
    }
}

static __inline volatile  void via_ofb_op6(
            const void *k, const void *c, const void *s, void *d, int l, void *v)
{   __asm
    {
        NEH_REKEY
        mov     ebx, (k)
        mov     edx, (c)
        mov     esi, (s)
        mov     edi, (d)
        mov     ecx, (l)
        mov     eax, (v)
        NEH_OFB
    }
}

#elif defined( __GNUC__ )

#define aligned_array(type, name, no, stride) type name[no] __attribute ((aligned(stride)))

/* GCC fails to align stack based variables as requested in an  */
/* attribute - this is a hack to overcome the problem           */

#define aligned_auto(type, name, no, stride)        \
    unsigned char _##name[no * sizeof(type) + 16];  \
    type *name = (type*)(16 * ((((unsigned long)(_##name)) + 15) / 16))

#define NEH_REKEY   asm("pushfl\n popfl\n\t")
#define NEH_ECB     asm(".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t")
#define NEH_CBC     asm(".byte 0xf3, 0x0f, 0xa7, 0xd0\n\t")
#define NEH_CFB     asm(".byte 0xf3, 0x0f, 0xa7, 0xe0\n\t")
#define NEH_OFB     asm(".byte 0xf3, 0x0f, 0xa7, 0xe8\n\t")
#define NEH_RNG     asm(".byte 0x0f, 0xa7, 0xc0\n\t");

static __inline int has_cpuid(void)
{   int val;
    asm("pushfl\n\t");
    asm("movl  0(%esp),%eax\n\t");
    asm("xor   $0x00200000,%eax\n\t");
    asm("pushl %eax\n\t");
    asm("popfl\n\t");
    asm("pushfl\n\t");
    asm("popl  %eax\n\t");
    asm("xorl  0(%esp),%edx\n\t");
    asm("andl  $0x00200000,%eax\n\t");
    asm("movl  %%eax,%0\n\t" : "=m" (val));
    asm("popfl\n\t");
    return val ? 1 : 0;
}

static __inline int is_via_cpu(void)
{   int val;
    asm("xorl %eax,%eax\n\t");
    asm("cpuid\n\t");
    asm("xorl %eax,%eax\n\t");
    asm("subl $0x746e6543,%ebx\n\t");
    asm("orl  %ebx,%eax\n\t");
    asm("subl $0x48727561,%edx\n\t");
    asm("orl  %edx,%eax\n\t");
    asm("subl $0x736c7561,%ecx\n\t");
    asm("orl  %ecx,%eax\n\t");
    asm("movl %%eax,%0\n\t" : "=m" (val));
    val = (val ? 0 : 1);
    via_flags = (val | NEH_CPU_READ);
    return val;
}

static __inline int read_via_flags(void)
{   unsigned char   val;
    asm("movl $0xc0000000,%eax\n\t");
    asm("cpuid\n\t");
    asm("movl $0xc0000001,%edx\n\t");
    asm("cmpl %edx,%eax\n\t");
    asm("setae %al\n\t");
    asm("movb %%al,%0\n\t" : "=m" (val));
    if(!val) return 0;
    asm("movl $0xc0000001,%eax\n\t");
    asm("cpuid\n\t");
    asm("movb %%dl,%0\n\t" : "=m" (val));
    val &= NEH_FLAGS_MASK;
    via_flags |= val;
    return (int) val;
}

static __inline int via_rng_in(void *buf)
{   int val;
    asm("pushl %edi\n\t");
    asm("movl %0,%%edi\n\t" : : "m" (buf));
    asm("xorl %edx,%edx\n\t");
    NEH_RNG
    asm("andl $0x0000001f,%eax\n\t");
    asm("movl %%eax,%0\n\t" : "=m" (val));
    asm("popl %edi\n\t");
    return val;
}

static __inline volatile  void via_ecb_op5(
            const void *k, const void *c, const void *s, void *d, int l)
{
    NEH_REKEY;
    asm("movl %0, %%ebx\n\t" : : "m" (k));
    asm("movl %0, %%edx\n\t" : : "m" (c));
    asm("movl %0, %%esi\n\t" : : "m" (s));
    asm("movl %0, %%edi\n\t" : : "m" (d));
    asm("movl %0, %%ecx\n\t" : : "m" (l));
    NEH_ECB;
}

static __inline volatile  void via_cbc_op6(
            const void *k, const void *c, const void *s, void *d, int l, void *v)
{
    NEH_REKEY;
    asm("movl %0, %%ebx\n\t" : : "m" (k));
    asm("movl %0, %%edx\n\t" : : "m" (c));
    asm("movl %0, %%esi\n\t" : : "m" (s));
    asm("movl %0, %%edi\n\t" : : "m" (d));
    asm("movl %0, %%ecx\n\t" : : "m" (l));
    asm("movl %0, %%eax\n\t" : : "m" (v));
    NEH_CBC;
}

static __inline volatile  void via_cbc_op7(
        const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
{
    NEH_REKEY;
    asm("movl %0, %%ebx\n\t" : : "m" (k));
    asm("movl %0, %%edx\n\t" : : "m" (c));
    asm("movl %0, %%esi\n\t" : : "m" (s));
    asm("movl %0, %%edi\n\t" : : "m" (d));
    asm("movl %0, %%ecx\n\t" : : "m" (l));
    asm("movl %0, %%eax\n\t" : : "m" (v));
    NEH_CBC;
    asm("movl %eax,%esi\n\t");
    asm("movl %0, %%edi\n\t" : : "m" (w));
    asm("movsl; movsl; movsl; movsl\n\t");
}

static __inline volatile  void via_cfb_op6(
            const void *k, const void *c, const void *s, void *d, int l, void *v)
{
    NEH_REKEY;
    asm("movl %0, %%ebx\n\t" : : "m" (k));
    asm("movl %0, %%edx\n\t" : : "m" (c));
    asm("movl %0, %%esi\n\t" : : "m" (s));
    asm("movl %0, %%edi\n\t" : : "m" (d));
    asm("movl %0, %%ecx\n\t" : : "m" (l));
    asm("movl %0, %%eax\n\t" : : "m" (v));
    NEH_CFB;
}

static __inline volatile  void via_cfb_op7(
        const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
{
    NEH_REKEY;
    asm("movl %0, %%ebx\n\t" : : "m" (k));
    asm("movl %0, %%edx\n\t" : : "m" (c));
    asm("movl %0, %%esi\n\t" : : "m" (s));
    asm("movl %0, %%edi\n\t" : : "m" (d));
    asm("movl %0, %%ecx\n\t" : : "m" (l));
    asm("movl %0, %%eax\n\t" : : "m" (v));
    NEH_CFB;
    asm("movl %eax,%esi\n\t");
    asm("movl %0, %%edi\n\t" : : "m" (w));
    asm("movsl; movsl; movsl; movsl\n\t");
}

static __inline volatile  void via_ofb_op6(
            const void *k, const void *c, const void *s, void *d, int l, void *v)
{
    NEH_REKEY;
    asm("movl %0, %%ebx\n\t" : : "m" (k));
    asm("movl %0, %%edx\n\t" : : "m" (c));
    asm("movl %0, %%esi\n\t" : : "m" (s));
    asm("movl %0, %%edi\n\t" : : "m" (d));
    asm("movl %0, %%ecx\n\t" : : "m" (l));
    asm("movl %0, %%eax\n\t" : : "m" (v));
    NEH_OFB;
}

#endif

static __inline int via_rng_available(void)
{
    return (via_flags & NEH_CPU_READ)
        ? (via_flags & NEH_CPU_IS_VIA) ? (read_via_flags() & NEH_RNG_AVAILABLE) : 0
        : has_cpuid() && is_via_cpu() && (read_via_flags() & NEH_RNG_AVAILABLE);
}

static __inline int via_ace_available(void)
{
    return (via_flags & NEH_CPU_READ)
        ? (via_flags & NEH_CPU_IS_VIA) ? (read_via_flags() & NEH_ACE_AVAILABLE) : 0
        : has_cpuid() && is_via_cpu() && (read_via_flags() & NEH_ACE_AVAILABLE);
}

static __inline int read_via_rng(void *buf, int count)
{   union
    {   long long       dummy;      /* force an aligned buffer      */
        unsigned char   bp[64];
    } aligned_buf;
    unsigned char   *p, *q;
    int             nbr, max_reads, lcnt = count;
    
    if(!via_rng_available()) return 0;

    do
    {
        max_reads = MAX_READ_ATTEMPTS;
        do
            nbr = via_rng_in(aligned_buf.bp);
        while
            (nbr == 0 && --max_reads);

        lcnt -= nbr;
        p = (unsigned char*)buf; q = aligned_buf.bp; 
        while(nbr--)
            *p++ = *q++;
    }
    while
        (lcnt && max_reads);

    return count - lcnt;
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?