Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
488 views
in Technique[技术] by (71.8m points)

c - GCC check if an expression will execute in a constant time

Let say I have the (x << n) | (x >> (-n & 63)) expression. There is nothing conditional in it. So, to my understanding, it will be executed in constant time.

Indeed, when I compile the following code using gcc -O3 -S:

#include <stdint.h>

// rotate left x by n places assuming n < 64
uint64_t rotl64(uint64_t x, uint8_t n) {
    return (x << n) | (x >> (-n & 63));
}

I get, on linux/amd64, the following output (which executes in constant time):

    .file   "test.c"
    .text
    .p2align 4
    .globl  rotl64
    .type   rotl64, @function
rotl64:
.LFB0:
    .cfi_startproc
    movq    %rdi, %rax
    movl    %esi, %ecx
    rolq    %cl, %rax
    ret
    .cfi_endproc
.LFE0:
    .size   rotl64, .-rotl64
    .ident  "GCC: (Alpine 9.3.0) 9.3.0"
    .section    .note.GNU-stack,"",@progbits

However, on linux/386 I get an output that contains conditional jumps:

    .file   "test.c"
    .text
    .p2align 4
    .globl  rotl64
    .type   rotl64, @function
rotl64:
.LFB0:
    .cfi_startproc
    pushl   %edi
    .cfi_def_cfa_offset 8
    .cfi_offset 7, -8
    pushl   %esi
    .cfi_def_cfa_offset 12
    .cfi_offset 6, -12
    movl    12(%esp), %eax
    movl    16(%esp), %edx
    movzbl  20(%esp), %ecx
    movl    %eax, %esi
    movl    %edx, %edi
    shldl   %esi, %edi
    sall    %cl, %esi
    testb   $32, %cl
    je  .L4
    movl    %esi, %edi
    xorl    %esi, %esi
.L4:
    negl    %ecx
    andl    $63, %ecx
    shrdl   %edx, %eax
    shrl    %cl, %edx
    testb   $32, %cl
    je  .L5
    movl    %edx, %eax
    xorl    %edx, %edx
.L5:
    orl %esi, %eax
    orl %edi, %edx
    popl    %esi
    .cfi_restore 6
    .cfi_def_cfa_offset 8
    popl    %edi
    .cfi_restore 7
    .cfi_def_cfa_offset 4
    ret
    .cfi_endproc
.LFE0:
    .size   rotl64, .-rotl64
    .ident  "GCC: (Alpine 9.3.0) 9.3.0"
    .section    .note.GNU-stack,"",@progbits

From what I understand, here the 64 bits operations have to be emulated, hence the need of conditional jumps.

Does GCC provide a builtin function that indicates if an expression will be compiled with no jumps?
If it isn't the case, how can I know if an expression will be executed in constant time?
Is this a problem for timing sensitive applications like security?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Does GCC provide a builtin function that indicates if an expression will be compiled with no jumps?

No.

If it isn't the case, how can I know if an expression will be executed in constant time?

By looking at the generated assembly code.

Is this a problem for timing sensitive applications like security?

Yes. That's why in these cases don't trust the compilers (and porters/package builders changing compiler settings) and rather implement it in assembly.

There are some constant time functions in general libc's, like in OpenBSD and FreeBSD. Like timingsafe_bcmp and timingsafe_memcmp, which are written in pure C, but their authors trust their packagers not to be like Debian or Ubuntu, who are assumed to break it.

Many other such functions are in the various security libraries itself, but even then you can safely assume that they are broken. For sure in OpenSSL and libsodium in many cases.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...