Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
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
25unsigned long int cx_rotl(unsigned long int x, unsigned char n)
26{
27 return (((x) << (n)) | ((x) >> (32 - (n))));
28}
29
30unsigned long int cx_rotr(unsigned long int x, unsigned char n)
31{
32 return (((x) >> (n)) | ((x) << ((32) - (n))));
33}
34
35unsigned long int cx_shr(unsigned long int x, unsigned char n)
36{
37 return ((x) >> (n));
38}
39#endif
40
41uint32_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
47void 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
68void 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}
83void 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
101uint64bits_t cx_rotr64(uint64bits_t x, unsigned int n)
102{
103 return (((x) >> (n)) | ((x) << ((64) - (n))));
104}
105uint64bits_t cx_rotl64(uint64bits_t x, unsigned int n)
106{
107 return (((x) << (n)) | ((x) >> ((64) - (n))));
108}
109uint64bits_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
173void 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
181uint8_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