1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2003-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include "e_os.h" 11e1051a39Sopenharmony_ci#include <string.h> 12e1051a39Sopenharmony_ci#include <limits.h> 13e1051a39Sopenharmony_ci#include <openssl/crypto.h> 14e1051a39Sopenharmony_ci#include "crypto/ctype.h" 15e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 16e1051a39Sopenharmony_ci#include "internal/thread_once.h" 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_ci#define DEFAULT_SEPARATOR ':' 19e1051a39Sopenharmony_ci#define CH_ZERO '\0' 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_cichar *CRYPTO_strdup(const char *str, const char* file, int line) 22e1051a39Sopenharmony_ci{ 23e1051a39Sopenharmony_ci char *ret; 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_ci if (str == NULL) 26e1051a39Sopenharmony_ci return NULL; 27e1051a39Sopenharmony_ci ret = CRYPTO_malloc(strlen(str) + 1, file, line); 28e1051a39Sopenharmony_ci if (ret != NULL) 29e1051a39Sopenharmony_ci strcpy(ret, str); 30e1051a39Sopenharmony_ci return ret; 31e1051a39Sopenharmony_ci} 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_cichar *CRYPTO_strndup(const char *str, size_t s, const char* file, int line) 34e1051a39Sopenharmony_ci{ 35e1051a39Sopenharmony_ci size_t maxlen; 36e1051a39Sopenharmony_ci char *ret; 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ci if (str == NULL) 39e1051a39Sopenharmony_ci return NULL; 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ci maxlen = OPENSSL_strnlen(str, s); 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ci ret = CRYPTO_malloc(maxlen + 1, file, line); 44e1051a39Sopenharmony_ci if (ret) { 45e1051a39Sopenharmony_ci memcpy(ret, str, maxlen); 46e1051a39Sopenharmony_ci ret[maxlen] = CH_ZERO; 47e1051a39Sopenharmony_ci } 48e1051a39Sopenharmony_ci return ret; 49e1051a39Sopenharmony_ci} 50e1051a39Sopenharmony_ci 51e1051a39Sopenharmony_civoid *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line) 52e1051a39Sopenharmony_ci{ 53e1051a39Sopenharmony_ci void *ret; 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci if (data == NULL || siz >= INT_MAX) 56e1051a39Sopenharmony_ci return NULL; 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ci ret = CRYPTO_malloc(siz, file, line); 59e1051a39Sopenharmony_ci if (ret == NULL) { 60e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 61e1051a39Sopenharmony_ci return NULL; 62e1051a39Sopenharmony_ci } 63e1051a39Sopenharmony_ci return memcpy(ret, data, siz); 64e1051a39Sopenharmony_ci} 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_cisize_t OPENSSL_strnlen(const char *str, size_t maxlen) 67e1051a39Sopenharmony_ci{ 68e1051a39Sopenharmony_ci const char *p; 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci for (p = str; maxlen-- != 0 && *p != CH_ZERO; ++p) ; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci return p - str; 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_cisize_t OPENSSL_strlcpy(char *dst, const char *src, size_t size) 76e1051a39Sopenharmony_ci{ 77e1051a39Sopenharmony_ci size_t l = 0; 78e1051a39Sopenharmony_ci for (; size > 1 && *src; size--) { 79e1051a39Sopenharmony_ci *dst++ = *src++; 80e1051a39Sopenharmony_ci l++; 81e1051a39Sopenharmony_ci } 82e1051a39Sopenharmony_ci if (size) 83e1051a39Sopenharmony_ci *dst = CH_ZERO; 84e1051a39Sopenharmony_ci return l + strlen(src); 85e1051a39Sopenharmony_ci} 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_cisize_t OPENSSL_strlcat(char *dst, const char *src, size_t size) 88e1051a39Sopenharmony_ci{ 89e1051a39Sopenharmony_ci size_t l = 0; 90e1051a39Sopenharmony_ci for (; size > 0 && *dst; size--, dst++) 91e1051a39Sopenharmony_ci l++; 92e1051a39Sopenharmony_ci return l + OPENSSL_strlcpy(dst, src, size); 93e1051a39Sopenharmony_ci} 94e1051a39Sopenharmony_ci 95e1051a39Sopenharmony_ciint OPENSSL_hexchar2int(unsigned char c) 96e1051a39Sopenharmony_ci{ 97e1051a39Sopenharmony_ci#ifdef CHARSET_EBCDIC 98e1051a39Sopenharmony_ci c = os_toebcdic[c]; 99e1051a39Sopenharmony_ci#endif 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci switch (c) { 102e1051a39Sopenharmony_ci case '0': 103e1051a39Sopenharmony_ci return 0; 104e1051a39Sopenharmony_ci case '1': 105e1051a39Sopenharmony_ci return 1; 106e1051a39Sopenharmony_ci case '2': 107e1051a39Sopenharmony_ci return 2; 108e1051a39Sopenharmony_ci case '3': 109e1051a39Sopenharmony_ci return 3; 110e1051a39Sopenharmony_ci case '4': 111e1051a39Sopenharmony_ci return 4; 112e1051a39Sopenharmony_ci case '5': 113e1051a39Sopenharmony_ci return 5; 114e1051a39Sopenharmony_ci case '6': 115e1051a39Sopenharmony_ci return 6; 116e1051a39Sopenharmony_ci case '7': 117e1051a39Sopenharmony_ci return 7; 118e1051a39Sopenharmony_ci case '8': 119e1051a39Sopenharmony_ci return 8; 120e1051a39Sopenharmony_ci case '9': 121e1051a39Sopenharmony_ci return 9; 122e1051a39Sopenharmony_ci case 'a': case 'A': 123e1051a39Sopenharmony_ci return 0x0A; 124e1051a39Sopenharmony_ci case 'b': case 'B': 125e1051a39Sopenharmony_ci return 0x0B; 126e1051a39Sopenharmony_ci case 'c': case 'C': 127e1051a39Sopenharmony_ci return 0x0C; 128e1051a39Sopenharmony_ci case 'd': case 'D': 129e1051a39Sopenharmony_ci return 0x0D; 130e1051a39Sopenharmony_ci case 'e': case 'E': 131e1051a39Sopenharmony_ci return 0x0E; 132e1051a39Sopenharmony_ci case 'f': case 'F': 133e1051a39Sopenharmony_ci return 0x0F; 134e1051a39Sopenharmony_ci } 135e1051a39Sopenharmony_ci return -1; 136e1051a39Sopenharmony_ci} 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_cistatic int hexstr2buf_sep(unsigned char *buf, size_t buf_n, size_t *buflen, 139e1051a39Sopenharmony_ci const char *str, const char sep) 140e1051a39Sopenharmony_ci{ 141e1051a39Sopenharmony_ci unsigned char *q; 142e1051a39Sopenharmony_ci unsigned char ch, cl; 143e1051a39Sopenharmony_ci int chi, cli; 144e1051a39Sopenharmony_ci const unsigned char *p; 145e1051a39Sopenharmony_ci size_t cnt; 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci for (p = (const unsigned char *)str, q = buf, cnt = 0; *p; ) { 148e1051a39Sopenharmony_ci ch = *p++; 149e1051a39Sopenharmony_ci /* A separator of CH_ZERO means there is no separator */ 150e1051a39Sopenharmony_ci if (ch == sep && sep != CH_ZERO) 151e1051a39Sopenharmony_ci continue; 152e1051a39Sopenharmony_ci cl = *p++; 153e1051a39Sopenharmony_ci if (!cl) { 154e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ODD_NUMBER_OF_DIGITS); 155e1051a39Sopenharmony_ci return 0; 156e1051a39Sopenharmony_ci } 157e1051a39Sopenharmony_ci cli = OPENSSL_hexchar2int(cl); 158e1051a39Sopenharmony_ci chi = OPENSSL_hexchar2int(ch); 159e1051a39Sopenharmony_ci if (cli < 0 || chi < 0) { 160e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ILLEGAL_HEX_DIGIT); 161e1051a39Sopenharmony_ci return 0; 162e1051a39Sopenharmony_ci } 163e1051a39Sopenharmony_ci cnt++; 164e1051a39Sopenharmony_ci if (q != NULL) { 165e1051a39Sopenharmony_ci if (cnt > buf_n) { 166e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER); 167e1051a39Sopenharmony_ci return 0; 168e1051a39Sopenharmony_ci } 169e1051a39Sopenharmony_ci *q++ = (unsigned char)((chi << 4) | cli); 170e1051a39Sopenharmony_ci } 171e1051a39Sopenharmony_ci } 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ci if (buflen != NULL) 174e1051a39Sopenharmony_ci *buflen = cnt; 175e1051a39Sopenharmony_ci return 1; 176e1051a39Sopenharmony_ci} 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_ci/* 179e1051a39Sopenharmony_ci * Given a string of hex digits convert to a buffer 180e1051a39Sopenharmony_ci */ 181e1051a39Sopenharmony_ciint OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen, 182e1051a39Sopenharmony_ci const char *str, const char sep) 183e1051a39Sopenharmony_ci{ 184e1051a39Sopenharmony_ci return hexstr2buf_sep(buf, buf_n, buflen, str, sep); 185e1051a39Sopenharmony_ci} 186e1051a39Sopenharmony_ci 187e1051a39Sopenharmony_ciunsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen, 188e1051a39Sopenharmony_ci const char sep) 189e1051a39Sopenharmony_ci{ 190e1051a39Sopenharmony_ci unsigned char *buf; 191e1051a39Sopenharmony_ci size_t buf_n, tmp_buflen; 192e1051a39Sopenharmony_ci 193e1051a39Sopenharmony_ci buf_n = strlen(str); 194e1051a39Sopenharmony_ci if (buf_n <= 1) { 195e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_HEX_STRING_TOO_SHORT); 196e1051a39Sopenharmony_ci return NULL; 197e1051a39Sopenharmony_ci } 198e1051a39Sopenharmony_ci buf_n /= 2; 199e1051a39Sopenharmony_ci if ((buf = OPENSSL_malloc(buf_n)) == NULL) { 200e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 201e1051a39Sopenharmony_ci return NULL; 202e1051a39Sopenharmony_ci } 203e1051a39Sopenharmony_ci 204e1051a39Sopenharmony_ci if (buflen != NULL) 205e1051a39Sopenharmony_ci *buflen = 0; 206e1051a39Sopenharmony_ci tmp_buflen = 0; 207e1051a39Sopenharmony_ci if (hexstr2buf_sep(buf, buf_n, &tmp_buflen, str, sep)) { 208e1051a39Sopenharmony_ci if (buflen != NULL) 209e1051a39Sopenharmony_ci *buflen = (long)tmp_buflen; 210e1051a39Sopenharmony_ci return buf; 211e1051a39Sopenharmony_ci } 212e1051a39Sopenharmony_ci OPENSSL_free(buf); 213e1051a39Sopenharmony_ci return NULL; 214e1051a39Sopenharmony_ci} 215e1051a39Sopenharmony_ci 216e1051a39Sopenharmony_ciunsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen) 217e1051a39Sopenharmony_ci{ 218e1051a39Sopenharmony_ci return ossl_hexstr2buf_sep(str, buflen, DEFAULT_SEPARATOR); 219e1051a39Sopenharmony_ci} 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_cistatic int buf2hexstr_sep(char *str, size_t str_n, size_t *strlength, 222e1051a39Sopenharmony_ci const unsigned char *buf, size_t buflen, 223e1051a39Sopenharmony_ci const char sep) 224e1051a39Sopenharmony_ci{ 225e1051a39Sopenharmony_ci static const char hexdig[] = "0123456789ABCDEF"; 226e1051a39Sopenharmony_ci const unsigned char *p; 227e1051a39Sopenharmony_ci char *q; 228e1051a39Sopenharmony_ci size_t i; 229e1051a39Sopenharmony_ci int has_sep = (sep != CH_ZERO); 230e1051a39Sopenharmony_ci size_t len = has_sep ? buflen * 3 : 1 + buflen * 2; 231e1051a39Sopenharmony_ci 232e1051a39Sopenharmony_ci if (len == 0) 233e1051a39Sopenharmony_ci ++len; 234e1051a39Sopenharmony_ci if (strlength != NULL) 235e1051a39Sopenharmony_ci *strlength = len; 236e1051a39Sopenharmony_ci if (str == NULL) 237e1051a39Sopenharmony_ci return 1; 238e1051a39Sopenharmony_ci 239e1051a39Sopenharmony_ci if (str_n < len) { 240e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER); 241e1051a39Sopenharmony_ci return 0; 242e1051a39Sopenharmony_ci } 243e1051a39Sopenharmony_ci 244e1051a39Sopenharmony_ci q = str; 245e1051a39Sopenharmony_ci for (i = 0, p = buf; i < buflen; i++, p++) { 246e1051a39Sopenharmony_ci *q++ = hexdig[(*p >> 4) & 0xf]; 247e1051a39Sopenharmony_ci *q++ = hexdig[*p & 0xf]; 248e1051a39Sopenharmony_ci if (has_sep) 249e1051a39Sopenharmony_ci *q++ = sep; 250e1051a39Sopenharmony_ci } 251e1051a39Sopenharmony_ci if (has_sep && buflen > 0) 252e1051a39Sopenharmony_ci --q; 253e1051a39Sopenharmony_ci *q = CH_ZERO; 254e1051a39Sopenharmony_ci 255e1051a39Sopenharmony_ci#ifdef CHARSET_EBCDIC 256e1051a39Sopenharmony_ci ebcdic2ascii(str, str, q - str - 1); 257e1051a39Sopenharmony_ci#endif 258e1051a39Sopenharmony_ci return 1; 259e1051a39Sopenharmony_ci} 260e1051a39Sopenharmony_ci 261e1051a39Sopenharmony_ciint OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlength, 262e1051a39Sopenharmony_ci const unsigned char *buf, size_t buflen, 263e1051a39Sopenharmony_ci const char sep) 264e1051a39Sopenharmony_ci{ 265e1051a39Sopenharmony_ci return buf2hexstr_sep(str, str_n, strlength, buf, buflen, sep); 266e1051a39Sopenharmony_ci} 267e1051a39Sopenharmony_ci 268e1051a39Sopenharmony_cichar *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep) 269e1051a39Sopenharmony_ci{ 270e1051a39Sopenharmony_ci char *tmp; 271e1051a39Sopenharmony_ci size_t tmp_n; 272e1051a39Sopenharmony_ci 273e1051a39Sopenharmony_ci if (buflen == 0) 274e1051a39Sopenharmony_ci return OPENSSL_zalloc(1); 275e1051a39Sopenharmony_ci 276e1051a39Sopenharmony_ci tmp_n = (sep != CH_ZERO) ? buflen * 3 : 1 + buflen * 2; 277e1051a39Sopenharmony_ci if ((tmp = OPENSSL_malloc(tmp_n)) == NULL) { 278e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 279e1051a39Sopenharmony_ci return NULL; 280e1051a39Sopenharmony_ci } 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ci if (buf2hexstr_sep(tmp, tmp_n, NULL, buf, buflen, sep)) 283e1051a39Sopenharmony_ci return tmp; 284e1051a39Sopenharmony_ci OPENSSL_free(tmp); 285e1051a39Sopenharmony_ci return NULL; 286e1051a39Sopenharmony_ci} 287e1051a39Sopenharmony_ci 288e1051a39Sopenharmony_ci 289e1051a39Sopenharmony_ci/* 290e1051a39Sopenharmony_ci * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its 291e1051a39Sopenharmony_ci * hex representation @@@ (Contents of buffer are always kept in ASCII, also 292e1051a39Sopenharmony_ci * on EBCDIC machines) 293e1051a39Sopenharmony_ci */ 294e1051a39Sopenharmony_cichar *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen) 295e1051a39Sopenharmony_ci{ 296e1051a39Sopenharmony_ci return ossl_buf2hexstr_sep(buf, buflen, ':'); 297e1051a39Sopenharmony_ci} 298e1051a39Sopenharmony_ci 299e1051a39Sopenharmony_ciint openssl_strerror_r(int errnum, char *buf, size_t buflen) 300e1051a39Sopenharmony_ci{ 301e1051a39Sopenharmony_ci#if defined(_MSC_VER) && _MSC_VER>=1400 && !defined(_WIN32_WCE) 302e1051a39Sopenharmony_ci return !strerror_s(buf, buflen, errnum); 303e1051a39Sopenharmony_ci#elif defined(_GNU_SOURCE) 304e1051a39Sopenharmony_ci char *err; 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ci /* 307e1051a39Sopenharmony_ci * GNU strerror_r may not actually set buf. 308e1051a39Sopenharmony_ci * It can return a pointer to some (immutable) static string in which case 309e1051a39Sopenharmony_ci * buf is left unused. 310e1051a39Sopenharmony_ci */ 311e1051a39Sopenharmony_ci err = strerror_r(errnum, buf, buflen); 312e1051a39Sopenharmony_ci if (err == NULL || buflen == 0) 313e1051a39Sopenharmony_ci return 0; 314e1051a39Sopenharmony_ci /* 315e1051a39Sopenharmony_ci * If err is statically allocated, err != buf and we need to copy the data. 316e1051a39Sopenharmony_ci * If err points somewhere inside buf, OPENSSL_strlcpy can handle this, 317e1051a39Sopenharmony_ci * since src and dest are not annotated with __restrict and the function 318e1051a39Sopenharmony_ci * reads src byte for byte and writes to dest. 319e1051a39Sopenharmony_ci * If err == buf we do not have to copy anything. 320e1051a39Sopenharmony_ci */ 321e1051a39Sopenharmony_ci if (err != buf) 322e1051a39Sopenharmony_ci OPENSSL_strlcpy(buf, err, buflen); 323e1051a39Sopenharmony_ci return 1; 324e1051a39Sopenharmony_ci#elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \ 325e1051a39Sopenharmony_ci (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) 326e1051a39Sopenharmony_ci /* 327e1051a39Sopenharmony_ci * We can use "real" strerror_r. The OpenSSL version differs in that it 328e1051a39Sopenharmony_ci * gives 1 on success and 0 on failure for consistency with other OpenSSL 329e1051a39Sopenharmony_ci * functions. Real strerror_r does it the other way around 330e1051a39Sopenharmony_ci */ 331e1051a39Sopenharmony_ci return !strerror_r(errnum, buf, buflen); 332e1051a39Sopenharmony_ci#else 333e1051a39Sopenharmony_ci char *err; 334e1051a39Sopenharmony_ci 335e1051a39Sopenharmony_ci /* Fall back to non-thread safe strerror()...its all we can do */ 336e1051a39Sopenharmony_ci if (buflen < 2) 337e1051a39Sopenharmony_ci return 0; 338e1051a39Sopenharmony_ci err = strerror(errnum); 339e1051a39Sopenharmony_ci /* Can this ever happen? */ 340e1051a39Sopenharmony_ci if (err == NULL) 341e1051a39Sopenharmony_ci return 0; 342e1051a39Sopenharmony_ci OPENSSL_strlcpy(buf, err, buflen); 343e1051a39Sopenharmony_ci return 1; 344e1051a39Sopenharmony_ci#endif 345e1051a39Sopenharmony_ci} 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_ciint OPENSSL_strcasecmp(const char *s1, const char *s2) 348e1051a39Sopenharmony_ci{ 349e1051a39Sopenharmony_ci int t; 350e1051a39Sopenharmony_ci 351e1051a39Sopenharmony_ci while ((t = ossl_tolower(*s1) - ossl_tolower(*s2++)) == 0) 352e1051a39Sopenharmony_ci if (*s1++ == '\0') 353e1051a39Sopenharmony_ci return 0; 354e1051a39Sopenharmony_ci return t; 355e1051a39Sopenharmony_ci} 356e1051a39Sopenharmony_ci 357e1051a39Sopenharmony_ciint OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n) 358e1051a39Sopenharmony_ci{ 359e1051a39Sopenharmony_ci int t; 360e1051a39Sopenharmony_ci size_t i; 361e1051a39Sopenharmony_ci 362e1051a39Sopenharmony_ci for (i = 0; i < n; i++) 363e1051a39Sopenharmony_ci if ((t = ossl_tolower(*s1) - ossl_tolower(*s2++)) != 0) 364e1051a39Sopenharmony_ci return t; 365e1051a39Sopenharmony_ci else if (*s1++ == '\0') 366e1051a39Sopenharmony_ci return 0; 367e1051a39Sopenharmony_ci return 0; 368e1051a39Sopenharmony_ci} 369