Embedded SDK
Embedded SDK
cx_utils.c
Go to the documentation of this file.
1 
2 /*******************************************************************************
3  * Ledger Nano S - Secure firmware
4  * (c) 2022 Ledger
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  ********************************************************************************/
18 
19 #include "cx_utils.h"
20 
21 /* ======================================================================= */
22 /* 32 BITS manipulation */
23 /* ======================================================================= */
24 #ifndef _CX_INLINE_U32
25 unsigned long int cx_rotl(unsigned long int x, unsigned char n)
26 {
27  return (((x) << (n)) | ((x) >> (32 - (n))));
28 }
29 
30 unsigned long int cx_rotr(unsigned long int x, unsigned char n)
31 {
32  return (((x) >> (n)) | ((x) << ((32) - (n))));
33 }
34 
35 unsigned long int cx_shr(unsigned long int x, unsigned char n)
36 {
37  return ((x) >> (n));
38 }
39 #endif
40 
41 uint32_t cx_swap_uint32(uint32_t v)
42 {
43  return (((v) << 24) & 0xFF000000U) | (((v) << 8) & 0x00FF0000U) | (((v) >> 8) & 0x0000FF00U)
44  | (((v) >> 24) & 0x000000FFU);
45 }
46 
47 void cx_swap_buffer32(uint32_t *v, size_t len)
48 {
49  while (len--) {
50 #ifdef ST31
51  unsigned int tmp;
52  tmp = ((unsigned char *) v)[len * 4 + 3];
53  ((unsigned char *) v)[len * 4 + 3] = ((unsigned char *) v)[len * 4];
54  ((unsigned char *) v)[len * 4] = tmp;
55  tmp = ((unsigned char *) v)[len * 4 + 2];
56  ((unsigned char *) v)[len * 4 + 2] = ((unsigned char *) v)[len * 4 + 1];
57  ((unsigned char *) v)[len * 4 + 1] = tmp;
58 #else
59  v[len] = cx_swap_uint32(v[len]);
60 #endif
61  }
62 }
63 
64 /* ======================================================================= */
65 /* 64 BITS manipulation */
66 /* ======================================================================= */
67 #ifndef NATIVE_64BITS // NO 64BITS
68 void cx_rotr64(uint64bits_t *x, unsigned int n)
69 {
70  unsigned long int sl_rot, sh_rot;
71  if (n >= 32) {
72  sl_rot = x->l;
73  x->l = x->h;
74  x->h = sl_rot;
75  n -= 32;
76  }
77  sh_rot = ((((x->h) & 0xFFFFFFFF) << (32 - n)));
78  sl_rot = ((((x->l) & 0xFFFFFFFF) << (32 - n)));
79  // rotate
80  x->h = ((x->h >> n) | sl_rot);
81  x->l = ((x->l >> n) | sh_rot);
82 }
83 void cx_shr64(uint64bits_t *x, unsigned char n)
84 {
85  unsigned long int sl_shr;
86 
87  if (n >= 32) {
88  x->l = (x->h);
89  x->h = 0;
90  n -= 32;
91  }
92 
93  sl_shr = ((((x->h) & 0xFFFFFFFF) << (32 - n)));
94  x->l = ((x->l) >> n) | sl_shr;
95  x->h = ((x->h) >> n);
96 }
97 
98 #else
99 
100 #ifndef _CX_INLINE_U64
101 uint64bits_t cx_rotr64(uint64bits_t x, unsigned int n)
102 {
103  return (((x) >> (n)) | ((x) << ((64) - (n))));
104 }
105 uint64bits_t cx_rotl64(uint64bits_t x, unsigned int n)
106 {
107  return (((x) << (n)) | ((x) >> ((64) - (n))));
108 }
109 uint64bits_t cx_shr64(uint64bits_t x, unsigned int n)
110 {
111  return ((x) >> (n));
112 }
113 #endif
114 
115 #endif
116 
117 #ifndef NATIVE_64BITS
119 {
120  unsigned long int h, l;
121  h = v->h;
122  l = v->l;
123  l = cx_swap_uint32(l);
124  h = cx_swap_uint32(h);
125  v->h = l;
126  v->l = h;
127 }
128 #else // HAVE_SYS_UINT64_SUPPORT
130 {
131  uint32_t h, l;
132  h = (uint32_t) ((v >> 32) & 0xFFFFFFFF);
133  l = (uint32_t) (v & 0xFFFFFFFF);
134  l = cx_swap_uint32(l);
135  h = cx_swap_uint32(h);
136  return (((uint64bits_t) l) << 32) | ((uint64bits_t) h);
137 }
138 #endif // HAVE_SYS_UINT64_SUPPORT
139 
141 {
142 #ifndef NATIVE_64BITS
143  while (len--) {
144  cx_swap_uint64(&v[len]);
145  }
146 #else // HAVE_SYS_UINT64_SUPPORT
147  uint64bits_t i;
148  while (len--) {
149  i = *v;
150  *v++ = cx_swap_uint64(i);
151  }
152 #endif // HAVE_SYS_UINT64_SUPPORT
153 }
154 
155 #ifndef NATIVE_64BITS
157 {
158  unsigned int carry;
159  unsigned long int addl;
160 
161  addl = x->l + y->l;
162  addl = ~addl;
163  carry = ((((x->l & y->l) | (x->l & ~y->l & addl) | (~x->l & y->l & addl)) >> 31) & 1);
164 
165  x->l = x->l + y->l;
166  x->h = x->h + y->h;
167  if (carry) {
168  x->h++;
169  }
170 }
171 #endif
172 
173 void cx_memxor(uint8_t *buf1, const uint8_t *buf2, size_t len)
174 {
175  size_t i;
176  for (i = 0; i < len; i++) {
177  buf1[i] ^= buf2[i];
178  }
179 }
180 
181 uint8_t cx_constant_time_eq(const uint8_t *buf1, uint8_t *buf2, size_t len)
182 {
183  uint8_t diff;
184  size_t i;
185  uint8_t is_eq;
186  for (diff = 0, i = 0; i < len; i++) {
187  diff |= buf1[i] ^ buf2[i];
188  }
189  is_eq = ((diff | -diff) >> 7) & 1;
190  return is_eq;
191 }
void cx_swap_buffer64(uint64bits_t *v, int len)
Definition: cx_utils.c:140
void cx_shr64(uint64bits_t *x, unsigned char n)
Definition: cx_utils.c:83
void cx_rotr64(uint64bits_t *x, unsigned int n)
Definition: cx_utils.c:68
uint32_t cx_swap_uint32(uint32_t v)
Definition: cx_utils.c:41
uint8_t cx_constant_time_eq(const uint8_t *buf1, uint8_t *buf2, size_t len)
Definition: cx_utils.c:181
void cx_add_64(uint64bits_t *x, uint64bits_t *y)
Definition: cx_utils.c:156
void cx_swap_uint64(uint64bits_t *v)
Definition: cx_utils.c:118
void cx_memxor(uint8_t *buf1, const uint8_t *buf2, size_t len)
Definition: cx_utils.c:173
void cx_swap_buffer32(uint32_t *v, size_t len)
Definition: cx_utils.c:47
#define cx_shr(x, n)
Definition: cx_utils.h:37
#define cx_rotl(x, n)
Definition: cx_utils.h:35
#define cx_rotr(x, n)
Definition: cx_utils.h:36
struct uint64_s uint64bits_t
Definition: lcx_common.h:58
64-bit types, native or by-hands, depending on target and/or compiler support.
Definition: lcx_common.h:49
uint32_t l
32 least significant bits
Definition: lcx_common.h:51
uint32_t h
32 most significant bits
Definition: lcx_common.h:52
unsigned char uint8_t
Definition: usbd_conf.h:53