Coverage Report

Created: 2022-12-08 06:10

/src/libgcrypt/mpi/mpih-const-time.c
Line
Count
Source (jump to first uncovered line)
1
/* mpih-const-time.c  -  Constant-time MPI helper functions
2
 *      Copyright (C) 2020  g10 Code GmbH
3
 *
4
 * This file is part of Libgcrypt.
5
 *
6
 * Libgcrypt is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation; either version 2.1 of
9
 * the License, or (at your option) any later version.
10
 *
11
 * Libgcrypt is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
#include <config.h>
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include "mpi-internal.h"
24
#include "g10lib.h"
25
26
233k
#define A_LIMB_1 ((mpi_limb_t)1)
27
28
/* These variables are used to generate masks from conditional operation
29
 * flag parameters.  Use of volatile prevents compiler optimizations from
30
 * converting AND-masking to conditional branches.  */
31
static volatile mpi_limb_t vzero = 0;
32
static volatile mpi_limb_t vone = 1;
33
34
/*
35
 *  W = U when OP_ENABLED=1
36
 *  otherwise, W keeps old value
37
 */
38
void
39
_gcry_mpih_set_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
40
                     unsigned long op_enable)
41
90.2M
{
42
90.2M
  mpi_size_t i;
43
90.2M
  mpi_limb_t mask1 = vzero - op_enable;
44
90.2M
  mpi_limb_t mask2 = op_enable - vone;
45
46
473M
  for (i = 0; i < usize; i++)
47
382M
    {
48
382M
      wp[i] = (wp[i] & mask2) | (up[i] & mask1);
49
382M
    }
50
90.2M
}
51
52
53
/*
54
 *  W = U + V when OP_ENABLED=1
55
 *  otherwise, W = U
56
 */
57
mpi_limb_t
58
_gcry_mpih_add_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
59
                       mpi_size_t usize, unsigned long op_enable)
60
23.2M
{
61
23.2M
  mpi_size_t i;
62
23.2M
  mpi_limb_t cy;
63
23.2M
  mpi_limb_t mask1 = vzero - op_enable;
64
23.2M
  mpi_limb_t mask2 = op_enable - vone;
65
66
23.2M
  cy = 0;
67
197M
  for (i = 0; i < usize; i++)
68
174M
    {
69
174M
      mpi_limb_t u = up[i];
70
174M
      mpi_limb_t x = u + vp[i];
71
174M
      mpi_limb_t cy1 = x < u;
72
174M
      mpi_limb_t cy2;
73
74
174M
      x = x + cy;
75
174M
      cy2 = x < cy;
76
174M
      cy = cy1 | cy2;
77
174M
      wp[i] = (u & mask2) | (x & mask1);
78
174M
    }
79
80
23.2M
  return cy & mask1;
81
23.2M
}
82
83
84
/*
85
 *  W = U - V when OP_ENABLED=1
86
 *  otherwise, W = U
87
 */
88
mpi_limb_t
89
_gcry_mpih_sub_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
90
                       mpi_size_t usize, unsigned long op_enable)
91
15.3M
{
92
15.3M
  mpi_size_t i;
93
15.3M
  mpi_limb_t cy;
94
15.3M
  mpi_limb_t mask1 = vzero - op_enable;
95
15.3M
  mpi_limb_t mask2 = op_enable - vone;
96
97
15.3M
  cy = 0;
98
130M
  for (i = 0; i < usize; i++)
99
115M
    {
100
115M
      mpi_limb_t u = up[i];
101
115M
      mpi_limb_t x = u - vp[i];
102
115M
      mpi_limb_t cy1 = x > u;
103
115M
      mpi_limb_t cy2;
104
105
115M
      cy2 = x < cy;
106
115M
      x = x - cy;
107
115M
      cy = cy1 | cy2;
108
115M
      wp[i] = (u & mask2) | (x & mask1);
109
115M
    }
110
111
15.3M
  return cy & mask1;
112
15.3M
}
113
114
115
/*
116
 *  Swap value of U and V when OP_ENABLED=1
117
 *  otherwise, no change
118
 */
119
void
120
_gcry_mpih_swap_cond (mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t usize,
121
                      unsigned long op_enable)
122
7.65M
{
123
7.65M
  mpi_size_t i;
124
7.65M
  mpi_limb_t mask1 = vzero - op_enable;
125
7.65M
  mpi_limb_t mask2 = op_enable - vone;
126
127
65.2M
  for (i = 0; i < usize; i++)
128
57.5M
    {
129
57.5M
      mpi_limb_t u = up[i];
130
57.5M
      mpi_limb_t v = vp[i];
131
57.5M
      up[i] = (u & mask2) | (v & mask1);
132
57.5M
      vp[i] = (u & mask1) | (v & mask2);
133
57.5M
    }
134
7.65M
}
135
136
137
/*
138
 *  W = -U when OP_ENABLED=1
139
 *  otherwise, W = U
140
 */
141
void
142
_gcry_mpih_abs_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
143
                     unsigned long op_enable)
144
7.65M
{
145
7.65M
  mpi_size_t i;
146
7.65M
  mpi_limb_t mask1 = vzero - op_enable;
147
7.65M
  mpi_limb_t mask2 = op_enable - vone;
148
7.65M
  mpi_limb_t cy = op_enable;
149
150
65.2M
  for (i = 0; i < usize; i++)
151
57.5M
    {
152
57.5M
      mpi_limb_t u = up[i];
153
57.5M
      mpi_limb_t x = ~u + cy;
154
155
57.5M
      cy = (x < ~u);
156
57.5M
      wp[i] = (u & mask2) | (x & mask1);
157
57.5M
    }
158
7.65M
}
159
160
161
/*
162
 * Allocating memory for W,
163
 * compute W = V % U, then return W
164
 */
165
mpi_ptr_t
166
_gcry_mpih_mod (mpi_ptr_t vp, mpi_size_t vsize,
167
                mpi_ptr_t up, mpi_size_t usize)
168
1.10k
{
169
1.10k
  int secure;
170
1.10k
  mpi_ptr_t rp;
171
1.10k
  mpi_size_t i;
172
173
1.10k
  secure = _gcry_is_secure (vp);
174
1.10k
  rp = mpi_alloc_limb_space (usize, secure);
175
1.10k
  MPN_ZERO (rp, usize);
176
177
234k
  for (i = 0; i < vsize * BITS_PER_MPI_LIMB; i++)
178
233k
    {
179
233k
      unsigned int j = vsize * BITS_PER_MPI_LIMB - 1 - i;
180
233k
      unsigned int limbno = j / BITS_PER_MPI_LIMB;
181
233k
      unsigned int bitno = j % BITS_PER_MPI_LIMB;
182
233k
      mpi_limb_t limb = vp[limbno];
183
233k
      unsigned int the_bit = ((limb & (A_LIMB_1 << bitno)) ? 1 : 0);
184
233k
      mpi_limb_t underflow;
185
233k
      mpi_limb_t overflow;
186
187
233k
      overflow = _gcry_mpih_lshift (rp, rp, usize, 1);
188
233k
      rp[0] |= the_bit;
189
190
233k
      underflow = _gcry_mpih_sub_n (rp, rp, up, usize);
191
233k
      mpih_add_n_cond (rp, rp, up, usize, overflow ^ underflow);
192
233k
    }
193
194
1.10k
  return rp;
195
1.10k
}
196
197
int
198
_gcry_mpih_cmp_ui (mpi_ptr_t up, mpi_size_t usize, unsigned long v)
199
12.9k
{
200
12.9k
  int is_all_zero = 1;
201
12.9k
  mpi_size_t i;
202
203
59.8k
  for (i = 1; i < usize; i++)
204
46.8k
    is_all_zero &= (up[i] == 0);
205
206
12.9k
  if (is_all_zero)
207
12.9k
    {
208
12.9k
      if (up[0] < v)
209
0
        return -1;
210
12.9k
      else if (up[0] > v)
211
134
        return 1;
212
12.8k
      else
213
12.8k
        return 0;
214
12.9k
    }
215
0
  return 1;
216
12.9k
}