File: const-time.c

package info (click to toggle)
grub2 2.14~git20250718.0e36779-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 60,688 kB
  • sloc: ansic: 541,811; asm: 68,074; sh: 9,803; cpp: 2,095; makefile: 1,895; python: 1,518; sed: 446; lex: 393; yacc: 268; awk: 85; lisp: 54; perl: 31
file content (88 lines) | stat: -rw-r--r-- 2,685 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* const-time.c  -  Constant-time functions
 *      Copyright (C) 2023  g10 Code GmbH
 *
 * This file is part of Libgcrypt.
 *
 * Libgcrypt is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * Libgcrypt is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, see <https://www.gnu.org/licenses/>.
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "g10lib.h"
#include "const-time.h"


#ifndef HAVE_GCC_ASM_VOLATILE_MEMORY
/* These variables are used to generate masks from conditional operation
 * flag parameters.  Use of volatile prevents compiler optimizations from
 * converting AND-masking to conditional branches.  */
volatile unsigned int _gcry_ct_vzero = 0;
volatile unsigned int _gcry_ct_vone = 1;
#endif


/*
 * Compare byte arrays of length LEN, return 1 if it's not same,
 * 0, otherwise.
 */
unsigned int
_gcry_ct_not_memequal (const void *b1, const void *b2, size_t len)
{
  const byte *a = b1;
  const byte *b = b2;
  int ab, ba;
  size_t i;

  /* Constant-time compare. */
  for (i = 0, ab = 0, ba = 0; i < len; i++)
    {
      /* If a[i] != b[i], either ab or ba will be negative. */
      ab |= a[i] - b[i];
      ba |= b[i] - a[i];
    }

  /* 'ab | ba' is negative when buffers are not equal, extract sign bit.  */
  return ((unsigned int)(ab | ba) >> (sizeof(unsigned int) * 8 - 1)) & 1;
}

/*
 * Compare byte arrays of length LEN, return 0 if it's not same,
 * 1, otherwise.
 */
unsigned int
_gcry_ct_memequal (const void *b1, const void *b2, size_t len)
{
  return _gcry_ct_not_memequal (b1, b2, len) ^ 1;
}

/*
 * Copy LEN bytes from memory area SRC to memory area DST, when
 * OP_ENABLED=1.  When DST <= SRC, the memory areas may overlap.  When
 * DST > SRC, the memory areas must not overlap.
 */
void
_gcry_ct_memmov_cond (void *dst, const void *src, size_t len,
		      unsigned long op_enable)
{
  /* Note: dual mask with AND/OR used for EM leakage mitigation */
  unsigned char mask1 = ct_ulong_gen_mask(op_enable);
  unsigned char mask2 = ct_ulong_gen_inv_mask(op_enable);
  unsigned char *b_dst = dst;
  const unsigned char *b_src = src;
  size_t i;

  for (i = 0; i < len; i++)
    b_dst[i] = (b_dst[i] & mask2) | (b_src[i] & mask1);
}