• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the License); you may
5  *  not use this file except in compliance with the License.
6  *
7  *  http://www.apache.org/licenses/LICENSE-2.0
8  */
9 
10 
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <stdint.h>
16 #include <gmssl/error.h>
17 
OPENSSL_hexchar2int(unsigned char c)18 int OPENSSL_hexchar2int(unsigned char c)
19 {
20     switch (c) {
21     case '0':
22         return 0;
23     case '1':
24         return 1;
25     case '2':
26         return 2;
27     case '3':
28         return 3;
29     case '4':
30           return 4;
31     case '5':
32           return 5;
33     case '6':
34           return 6;
35     case '7':
36           return 7;
37     case '8':
38           return 8;
39     case '9':
40           return 9;
41     case 'a':
42     case 'A':
43           return 0x0A;
44     case 'b': case 'B':
45           return 0x0B;
46     case 'c': case 'C':
47           return 0x0C;
48     case 'd': case 'D':
49           return 0x0D;
50     case 'e': case 'E':
51           return 0x0E;
52     case 'f': case 'F':
53           return 0x0F;
54     }
55     return -1;
56 }
57 
OPENSSL_hexstr2buf(const char * str,size_t * len)58 unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len)
59 {
60     unsigned char *hexbuf, *q;
61     unsigned char ch, cl;
62     int chi, cli;
63     const unsigned char *p;
64     size_t s;
65 
66     s = strlen(str);
67     if ((hexbuf = malloc(s >> 1)) == NULL) {
68         return NULL;
69     }
70     for (p = (const unsigned char *)str, q = hexbuf; *p; ) {
71         ch = *p++;
72         if (ch == ':')
73             continue;
74         cl = *p++;
75         if (!cl) {
76             //CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ODD_NUMBER_OF_DIGITS);
77             free(hexbuf);
78             return NULL;
79         }
80         cli = OPENSSL_hexchar2int(cl);
81         chi = OPENSSL_hexchar2int(ch);
82         if (cli < 0 || chi < 0) {
83             free(hexbuf);
84             //CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT);
85             return NULL;
86         }
87         *q++ = (unsigned char)((chi << 4) | cli);
88     }
89 
90     if (len)
91         *len = q - hexbuf;
92     return hexbuf;
93 }
94 
95 
hexchar2int(char c)96 static int hexchar2int(char c)
97 {
98 	if      ('0' <= c && c <= '9') return c - '0';
99 	else if ('a' <= c && c <= 'f') return c - 'a' + 10;
100 	else if ('A' <= c && c <= 'F') return c - 'A' + 10;
101 	else return -1;
102 }
103 
hex2bin(const char * in,size_t inlen,uint8_t * out)104 int hex2bin(const char *in, size_t inlen, uint8_t *out)
105 {
106 	int c;
107 	if (inlen % 2) {
108 		error_print_msg("hex %s len = %zu\n", in, inlen);
109 		return -1;
110 	}
111 
112 	while (inlen) {
113 		if ((c = hexchar2int(*in++)) < 0) {
114 			error_print_msg("%d", 5);
115 			return -1;
116 		}
117 		*out = (uint8_t)c << 4;
118 		if ((c = hexchar2int(*in++)) < 0) {
119 			error_print();
120 			return -1;
121 		}
122 		*out |= (uint8_t)c;
123 		inlen -= 2;
124 		out++;
125 	}
126 	return 1;
127 }
128 
hex_to_bytes(const char * in,size_t inlen,uint8_t * out,size_t * outlen)129 int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen)
130 {
131 	*outlen = inlen/2;
132 	return hex2bin(in, inlen, out);
133 }
134 
135 
memxor(void * r,const void * a,size_t len)136 void memxor(void *r, const void *a, size_t len)
137 {
138 	uint8_t *pr = r;
139 	const uint8_t *pa = a;
140 	size_t i;
141 	for (i = 0; i < len; i++) {
142 		pr[i] ^= pa[i];
143 	}
144 
145 }
146 
147 
gmssl_memxor(void * r,const void * a,const void * b,size_t len)148 void gmssl_memxor(void *r, const void *a, const void *b, size_t len)
149 {
150 	uint8_t *pr = r;
151 	const uint8_t *pa = a;
152 	const uint8_t *pb = b;
153 	size_t i;
154 	for (i = 0; i < len; i++) {
155 		pr[i] = pa[i] ^ pb[i];
156 	}
157 }
158 
159 
160 // Note: comments and code from OpenSSL crypto/cryptlib.c:CRYPTO_memcmp()
161 /* volatile unsigned char* pointers are there because
162  * 1. Accessing a variable declared volatile via a pointer
163  *    that lacks a volatile qualifier causes undefined behavior.
164  * 2. When the variable itself is not volatile the compiler is
165  *    not required to keep all those reads and can convert
166  *    this into canonical memcmp() which doesn't read the whole block.
167  * Pointers to volatile resolve the first problem fully. The second
168  * problem cannot be resolved in any Standard-compliant way but this
169  * works the problem around. Compilers typically react to
170  * pointers to volatile by preserving the reads and writes through them.
171  * The latter is not required by the Standard if the memory pointed to
172  * is not volatile.
173  * Pointers themselves are volatile in the function signature to work
174  * around a subtle bug in gcc 4.6+ which causes writes through
175  * pointers to volatile to not be emitted in some rare,
176  * never needed in real life, pieces of code.
177  */
gmssl_secure_memcmp(const volatile void * volatile in_a,const volatile void * volatile in_b,size_t len)178 int gmssl_secure_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len)
179 {
180 	size_t i;
181 	const volatile unsigned char *a = in_a;
182 	const volatile unsigned char *b = in_b;
183 	unsigned char x = 0;
184 
185 	for (i = 0; i < len; i++) {
186 		x |= a[i] ^ b[i];
187 	}
188 
189 	return x;
190 }
191 
192 /*
193  * Pointer to memset is volatile so that compiler must de-reference
194  * the pointer and can't assume that it points to any function in
195  * particular (such as memset, which it then might further "optimize")
196  */
197 typedef void *(*memset_t)(void *, int, size_t);
198 
199 static volatile memset_t memset_func = memset;
200 
gmssl_secure_clear(void * ptr,size_t len)201 void gmssl_secure_clear(void *ptr, size_t len)
202 {
203 	memset_func(ptr, 0, len);
204 }
205 
mem_is_zero(const uint8_t * buf,size_t len)206 int mem_is_zero(const uint8_t *buf, size_t len)
207 {
208 	int ret = 1;
209 	size_t i;
210 	for (i = 0; i < len; i++) {
211 		if (buf[i]) ret = 0;
212 	}
213 	return ret;
214 }
215 
216 
217 
218 
219 
220