enc.c revision 296465
197403Sobrien/* apps/enc.c */ 297403Sobrien/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 397403Sobrien * All rights reserved. 497403Sobrien * 597403Sobrien * This package is an SSL implementation written 697403Sobrien * by Eric Young (eay@cryptsoft.com). 797403Sobrien * The implementation was written so as to conform with Netscapes SSL. 897403Sobrien * 997403Sobrien * This library is free for commercial and non-commercial use as long as 1097403Sobrien * the following conditions are aheared to. The following conditions 1197403Sobrien * apply to all code found in this distribution, be it the RC4, RSA, 1297403Sobrien * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1397403Sobrien * included with this distribution is covered by the same copyright terms 1497403Sobrien * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1597403Sobrien * 16169691Skan * Copyright remains Eric Young's, and as such any Copyright notices in 1797403Sobrien * the code are not to be removed. 1897403Sobrien * If this package is used in a product, Eric Young should be given attribution 1997403Sobrien * as the author of the parts of the library used. 2097403Sobrien * This can be in the form of a textual message at program startup or 2197403Sobrien * in documentation (online or textual) provided with the package. 2297403Sobrien * 2397403Sobrien * Redistribution and use in source and binary forms, with or without 2497403Sobrien * modification, are permitted provided that the following conditions 2597403Sobrien * are met: 2697403Sobrien * 1. Redistributions of source code must retain the copyright 2797403Sobrien * notice, this list of conditions and the following disclaimer. 28132720Skan * 2. Redistributions in binary form must reproduce the above copyright 29132720Skan * notice, this list of conditions and the following disclaimer in the 3097403Sobrien * documentation and/or other materials provided with the distribution. 3197403Sobrien * 3. All advertising materials mentioning features or use of this software 3297403Sobrien * must display the following acknowledgement: 3397403Sobrien * "This product includes cryptographic software written by 3497403Sobrien * Eric Young (eay@cryptsoft.com)" 3597403Sobrien * The word 'cryptographic' can be left out if the rouines from the library 3697403Sobrien * being used are not cryptographic related :-). 3797403Sobrien * 4. If you include any Windows specific code (or a derivative thereof) from 3897403Sobrien * the apps directory (application code) you must include an acknowledgement: 3997403Sobrien * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40132720Skan * 4197403Sobrien * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4297403Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4397403Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4497403Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4597403Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4697403Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4797403Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4897403Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59#include <stdio.h> 60#include <stdlib.h> 61#include <string.h> 62#include "apps.h" 63#include <openssl/bio.h> 64#include <openssl/err.h> 65#include <openssl/evp.h> 66#include <openssl/objects.h> 67#include <openssl/x509.h> 68#include <openssl/rand.h> 69#include <openssl/pem.h> 70#include <ctype.h> 71 72int set_hex(char *in, unsigned char *out, int size); 73#undef SIZE 74#undef BSIZE 75#undef PROG 76 77#define SIZE (512) 78#define BSIZE (8*1024) 79#define PROG enc_main 80 81static void show_ciphers(const OBJ_NAME *name, void *bio_) 82{ 83 BIO *bio = bio_; 84 static int n; 85 86 if (!islower((unsigned char)*name->name)) 87 return; 88 89 BIO_printf(bio, "-%-25s", name->name); 90 if (++n == 3) { 91 BIO_printf(bio, "\n"); 92 n = 0; 93 } else 94 BIO_printf(bio, " "); 95} 96 97int MAIN(int, char **); 98 99int MAIN(int argc, char **argv) 100{ 101 static const char magic[] = "Salted__"; 102 char mbuf[sizeof magic - 1]; 103 char *strbuf = NULL; 104 unsigned char *buff = NULL, *bufsize = NULL; 105 int bsize = BSIZE, verbose = 0; 106 int ret = 1, inl; 107 int nopad = 0; 108 unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; 109 unsigned char salt[PKCS5_SALT_LEN]; 110 char *str = NULL, *passarg = NULL, *pass = NULL; 111 char *hkey = NULL, *hiv = NULL, *hsalt = NULL; 112 char *md = NULL; 113 int enc = 1, printkey = 0, i, base64 = 0; 114 int debug = 0, olb64 = 0, nosalt = 0; 115 const EVP_CIPHER *cipher = NULL, *c; 116 EVP_CIPHER_CTX *ctx = NULL; 117 char *inf = NULL, *outf = NULL; 118 BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = 119 NULL, *wbio = NULL; 120#define PROG_NAME_SIZE 39 121 char pname[PROG_NAME_SIZE + 1]; 122#ifndef OPENSSL_NO_ENGINE 123 char *engine = NULL; 124#endif 125 const EVP_MD *dgst = NULL; 126 int non_fips_allow = 0; 127 128 apps_startup(); 129 130 if (bio_err == NULL) 131 if ((bio_err = BIO_new(BIO_s_file())) != NULL) 132 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 133 134 if (!load_config(bio_err, NULL)) 135 goto end; 136 137 /* first check the program name */ 138 program_name(argv[0], pname, sizeof pname); 139 if (strcmp(pname, "base64") == 0) 140 base64 = 1; 141 142 cipher = EVP_get_cipherbyname(pname); 143 if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0)) { 144 BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 145 goto bad; 146 } 147 148 argc--; 149 argv++; 150 while (argc >= 1) { 151 if (strcmp(*argv, "-e") == 0) 152 enc = 1; 153 else if (strcmp(*argv, "-in") == 0) { 154 if (--argc < 1) 155 goto bad; 156 inf = *(++argv); 157 } else if (strcmp(*argv, "-out") == 0) { 158 if (--argc < 1) 159 goto bad; 160 outf = *(++argv); 161 } else if (strcmp(*argv, "-pass") == 0) { 162 if (--argc < 1) 163 goto bad; 164 passarg = *(++argv); 165 } 166#ifndef OPENSSL_NO_ENGINE 167 else if (strcmp(*argv, "-engine") == 0) { 168 if (--argc < 1) 169 goto bad; 170 engine = *(++argv); 171 } 172#endif 173 else if (strcmp(*argv, "-d") == 0) 174 enc = 0; 175 else if (strcmp(*argv, "-p") == 0) 176 printkey = 1; 177 else if (strcmp(*argv, "-v") == 0) 178 verbose = 1; 179 else if (strcmp(*argv, "-nopad") == 0) 180 nopad = 1; 181 else if (strcmp(*argv, "-salt") == 0) 182 nosalt = 0; 183 else if (strcmp(*argv, "-nosalt") == 0) 184 nosalt = 1; 185 else if (strcmp(*argv, "-debug") == 0) 186 debug = 1; 187 else if (strcmp(*argv, "-P") == 0) 188 printkey = 2; 189 else if (strcmp(*argv, "-A") == 0) 190 olb64 = 1; 191 else if (strcmp(*argv, "-a") == 0) 192 base64 = 1; 193 else if (strcmp(*argv, "-base64") == 0) 194 base64 = 1; 195 else if (strcmp(*argv, "-bufsize") == 0) { 196 if (--argc < 1) 197 goto bad; 198 bufsize = (unsigned char *)*(++argv); 199 } else if (strcmp(*argv, "-k") == 0) { 200 if (--argc < 1) 201 goto bad; 202 str = *(++argv); 203 } else if (strcmp(*argv, "-kfile") == 0) { 204 static char buf[128]; 205 FILE *infile; 206 char *file; 207 208 if (--argc < 1) 209 goto bad; 210 file = *(++argv); 211 infile = fopen(file, "r"); 212 if (infile == NULL) { 213 BIO_printf(bio_err, "unable to read key from '%s'\n", file); 214 goto bad; 215 } 216 buf[0] = '\0'; 217 if (!fgets(buf, sizeof buf, infile)) { 218 BIO_printf(bio_err, "unable to read key from '%s'\n", file); 219 goto bad; 220 } 221 fclose(infile); 222 i = strlen(buf); 223 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 224 buf[--i] = '\0'; 225 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 226 buf[--i] = '\0'; 227 if (i < 1) { 228 BIO_printf(bio_err, "zero length password\n"); 229 goto bad; 230 } 231 str = buf; 232 } else if (strcmp(*argv, "-K") == 0) { 233 if (--argc < 1) 234 goto bad; 235 hkey = *(++argv); 236 } else if (strcmp(*argv, "-S") == 0) { 237 if (--argc < 1) 238 goto bad; 239 hsalt = *(++argv); 240 } else if (strcmp(*argv, "-iv") == 0) { 241 if (--argc < 1) 242 goto bad; 243 hiv = *(++argv); 244 } else if (strcmp(*argv, "-md") == 0) { 245 if (--argc < 1) 246 goto bad; 247 md = *(++argv); 248 } else if (strcmp(*argv, "-non-fips-allow") == 0) 249 non_fips_allow = 1; 250 else if ((argv[0][0] == '-') && 251 ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { 252 cipher = c; 253 } else if (strcmp(*argv, "-none") == 0) 254 cipher = NULL; 255 else { 256 BIO_printf(bio_err, "unknown option '%s'\n", *argv); 257 bad: 258 BIO_printf(bio_err, "options are\n"); 259 BIO_printf(bio_err, "%-14s input file\n", "-in <file>"); 260 BIO_printf(bio_err, "%-14s output file\n", "-out <file>"); 261 BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass <arg>"); 262 BIO_printf(bio_err, "%-14s encrypt\n", "-e"); 263 BIO_printf(bio_err, "%-14s decrypt\n", "-d"); 264 BIO_printf(bio_err, 265 "%-14s base64 encode/decode, depending on encryption flag\n", 266 "-a/-base64"); 267 BIO_printf(bio_err, "%-14s passphrase is the next argument\n", 268 "-k"); 269 BIO_printf(bio_err, 270 "%-14s passphrase is the first line of the file argument\n", 271 "-kfile"); 272 BIO_printf(bio_err, 273 "%-14s the next argument is the md to use to create a key\n", 274 "-md"); 275 BIO_printf(bio_err, 276 "%-14s from a passphrase. One of md2, md5, sha or sha1\n", 277 ""); 278 BIO_printf(bio_err, "%-14s key/iv in hex is the next argument\n", 279 "-K/-iv"); 280 BIO_printf(bio_err, "%-14s print the iv/key (then exit if -P)\n", 281 "-[pP]"); 282 BIO_printf(bio_err, "%-14s buffer size\n", "-bufsize <n>"); 283#ifndef OPENSSL_NO_ENGINE 284 BIO_printf(bio_err, 285 "%-14s use engine e, possibly a hardware device.\n", 286 "-engine e"); 287#endif 288 289 BIO_printf(bio_err, "Cipher Types\n"); 290 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, 291 show_ciphers, bio_err); 292 BIO_printf(bio_err, "\n"); 293 294 goto end; 295 } 296 argc--; 297 argv++; 298 } 299 300#ifndef OPENSSL_NO_ENGINE 301 setup_engine(bio_err, engine, 0); 302#endif 303 304 if (md && (dgst = EVP_get_digestbyname(md)) == NULL) { 305 BIO_printf(bio_err, "%s is an unsupported message digest type\n", md); 306 goto end; 307 } 308 309 if (dgst == NULL) { 310 if (in_FIPS_mode) 311 dgst = EVP_sha1(); 312 else 313 dgst = EVP_md5(); 314 } 315 316 if (bufsize != NULL) { 317 unsigned long n; 318 319 for (n = 0; *bufsize; bufsize++) { 320 i = *bufsize; 321 if ((i <= '9') && (i >= '0')) 322 n = n * 10 + i - '0'; 323 else if (i == 'k') { 324 n *= 1024; 325 bufsize++; 326 break; 327 } 328 } 329 if (*bufsize != '\0') { 330 BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 331 goto end; 332 } 333 334 /* It must be large enough for a base64 encoded line */ 335 if (base64 && n < 80) 336 n = 80; 337 338 bsize = (int)n; 339 if (verbose) 340 BIO_printf(bio_err, "bufsize=%d\n", bsize); 341 } 342 343 strbuf = OPENSSL_malloc(SIZE); 344 buff = (unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); 345 if ((buff == NULL) || (strbuf == NULL)) { 346 BIO_printf(bio_err, "OPENSSL_malloc failure %ld\n", 347 (long)EVP_ENCODE_LENGTH(bsize)); 348 goto end; 349 } 350 351 in = BIO_new(BIO_s_file()); 352 out = BIO_new(BIO_s_file()); 353 if ((in == NULL) || (out == NULL)) { 354 ERR_print_errors(bio_err); 355 goto end; 356 } 357 if (debug) { 358 BIO_set_callback(in, BIO_debug_callback); 359 BIO_set_callback(out, BIO_debug_callback); 360 BIO_set_callback_arg(in, (char *)bio_err); 361 BIO_set_callback_arg(out, (char *)bio_err); 362 } 363 364 if (inf == NULL) { 365 if (bufsize != NULL) 366 setvbuf(stdin, (char *)NULL, _IONBF, 0); 367 BIO_set_fp(in, stdin, BIO_NOCLOSE); 368 } else { 369 if (BIO_read_filename(in, inf) <= 0) { 370 perror(inf); 371 goto end; 372 } 373 } 374 375 if (!str && passarg) { 376 if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { 377 BIO_printf(bio_err, "Error getting password\n"); 378 goto end; 379 } 380 str = pass; 381 } 382 383 if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { 384 for (;;) { 385 char buf[200]; 386 387 BIO_snprintf(buf, sizeof buf, "enter %s %s password:", 388 OBJ_nid2ln(EVP_CIPHER_nid(cipher)), 389 (enc) ? "encryption" : "decryption"); 390 strbuf[0] = '\0'; 391 i = EVP_read_pw_string((char *)strbuf, SIZE, buf, enc); 392 if (i == 0) { 393 if (strbuf[0] == '\0') { 394 ret = 1; 395 goto end; 396 } 397 str = strbuf; 398 break; 399 } 400 if (i < 0) { 401 BIO_printf(bio_err, "bad password read\n"); 402 goto end; 403 } 404 } 405 } 406 407 if (outf == NULL) { 408 BIO_set_fp(out, stdout, BIO_NOCLOSE); 409 if (bufsize != NULL) 410 setvbuf(stdout, (char *)NULL, _IONBF, 0); 411#ifdef OPENSSL_SYS_VMS 412 { 413 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 414 out = BIO_push(tmpbio, out); 415 } 416#endif 417 } else { 418 if (BIO_write_filename(out, outf) <= 0) { 419 perror(outf); 420 goto end; 421 } 422 } 423 424 rbio = in; 425 wbio = out; 426 427 if (base64) { 428 if ((b64 = BIO_new(BIO_f_base64())) == NULL) 429 goto end; 430 if (debug) { 431 BIO_set_callback(b64, BIO_debug_callback); 432 BIO_set_callback_arg(b64, (char *)bio_err); 433 } 434 if (olb64) 435 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 436 if (enc) 437 wbio = BIO_push(b64, wbio); 438 else 439 rbio = BIO_push(b64, rbio); 440 } 441 442 if (cipher != NULL) { 443 /* 444 * Note that str is NULL if a key was passed on the command line, so 445 * we get no salt in that case. Is this a bug? 446 */ 447 if (str != NULL) { 448 /* 449 * Salt handling: if encrypting generate a salt and write to 450 * output BIO. If decrypting read salt from input BIO. 451 */ 452 unsigned char *sptr; 453 if (nosalt) 454 sptr = NULL; 455 else { 456 if (enc) { 457 if (hsalt) { 458 if (!set_hex(hsalt, salt, sizeof salt)) { 459 BIO_printf(bio_err, "invalid hex salt value\n"); 460 goto end; 461 } 462 } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0) 463 goto end; 464 /* 465 * If -P option then don't bother writing 466 */ 467 if ((printkey != 2) 468 && (BIO_write(wbio, magic, 469 sizeof magic - 1) != sizeof magic - 1 470 || BIO_write(wbio, 471 (char *)salt, 472 sizeof salt) != sizeof salt)) { 473 BIO_printf(bio_err, "error writing output file\n"); 474 goto end; 475 } 476 } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf 477 || BIO_read(rbio, 478 (unsigned char *)salt, 479 sizeof salt) != sizeof salt) { 480 BIO_printf(bio_err, "error reading input file\n"); 481 goto end; 482 } else if (memcmp(mbuf, magic, sizeof magic - 1)) { 483 BIO_printf(bio_err, "bad magic number\n"); 484 goto end; 485 } 486 487 sptr = salt; 488 } 489 490 EVP_BytesToKey(cipher, dgst, sptr, 491 (unsigned char *)str, strlen(str), 1, key, iv); 492 /* 493 * zero the complete buffer or the string passed from the command 494 * line bug picked up by Larry J. Hughes Jr. <hughes@indiana.edu> 495 */ 496 if (str == strbuf) 497 OPENSSL_cleanse(str, SIZE); 498 else 499 OPENSSL_cleanse(str, strlen(str)); 500 } 501 if ((hiv != NULL) && !set_hex(hiv, iv, sizeof iv)) { 502 BIO_printf(bio_err, "invalid hex iv value\n"); 503 goto end; 504 } 505 if ((hiv == NULL) && (str == NULL) 506 && EVP_CIPHER_iv_length(cipher) != 0) { 507 /* 508 * No IV was explicitly set and no IV was generated during 509 * EVP_BytesToKey. Hence the IV is undefined, making correct 510 * decryption impossible. 511 */ 512 BIO_printf(bio_err, "iv undefined\n"); 513 goto end; 514 } 515 if ((hkey != NULL) && !set_hex(hkey, key, sizeof key)) { 516 BIO_printf(bio_err, "invalid hex key value\n"); 517 goto end; 518 } 519 520 if ((benc = BIO_new(BIO_f_cipher())) == NULL) 521 goto end; 522 523 /* 524 * Since we may be changing parameters work on the encryption context 525 * rather than calling BIO_set_cipher(). 526 */ 527 528 BIO_get_cipher_ctx(benc, &ctx); 529 530 if (non_fips_allow) 531 EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); 532 533 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { 534 BIO_printf(bio_err, "Error setting cipher %s\n", 535 EVP_CIPHER_name(cipher)); 536 ERR_print_errors(bio_err); 537 goto end; 538 } 539 540 if (nopad) 541 EVP_CIPHER_CTX_set_padding(ctx, 0); 542 543 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { 544 BIO_printf(bio_err, "Error setting cipher %s\n", 545 EVP_CIPHER_name(cipher)); 546 ERR_print_errors(bio_err); 547 goto end; 548 } 549 550 if (debug) { 551 BIO_set_callback(benc, BIO_debug_callback); 552 BIO_set_callback_arg(benc, (char *)bio_err); 553 } 554 555 if (printkey) { 556 if (!nosalt) { 557 printf("salt="); 558 for (i = 0; i < (int)sizeof(salt); i++) 559 printf("%02X", salt[i]); 560 printf("\n"); 561 } 562 if (cipher->key_len > 0) { 563 printf("key="); 564 for (i = 0; i < cipher->key_len; i++) 565 printf("%02X", key[i]); 566 printf("\n"); 567 } 568 if (cipher->iv_len > 0) { 569 printf("iv ="); 570 for (i = 0; i < cipher->iv_len; i++) 571 printf("%02X", iv[i]); 572 printf("\n"); 573 } 574 if (printkey == 2) { 575 ret = 0; 576 goto end; 577 } 578 } 579 } 580 581 /* Only encrypt/decrypt as we write the file */ 582 if (benc != NULL) 583 wbio = BIO_push(benc, wbio); 584 585 for (;;) { 586 inl = BIO_read(rbio, (char *)buff, bsize); 587 if (inl <= 0) 588 break; 589 if (BIO_write(wbio, (char *)buff, inl) != inl) { 590 BIO_printf(bio_err, "error writing output file\n"); 591 goto end; 592 } 593 } 594 if (!BIO_flush(wbio)) { 595 BIO_printf(bio_err, "bad decrypt\n"); 596 goto end; 597 } 598 599 ret = 0; 600 if (verbose) { 601 BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 602 BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 603 } 604 end: 605 ERR_print_errors(bio_err); 606 if (strbuf != NULL) 607 OPENSSL_free(strbuf); 608 if (buff != NULL) 609 OPENSSL_free(buff); 610 if (in != NULL) 611 BIO_free(in); 612 if (out != NULL) 613 BIO_free_all(out); 614 if (benc != NULL) 615 BIO_free(benc); 616 if (b64 != NULL) 617 BIO_free(b64); 618 if (pass) 619 OPENSSL_free(pass); 620 apps_shutdown(); 621 OPENSSL_EXIT(ret); 622} 623 624int set_hex(char *in, unsigned char *out, int size) 625{ 626 int i, n; 627 unsigned char j; 628 629 n = strlen(in); 630 if (n > (size * 2)) { 631 BIO_printf(bio_err, "hex string is too long\n"); 632 return (0); 633 } 634 memset(out, 0, size); 635 for (i = 0; i < n; i++) { 636 j = (unsigned char)*in; 637 *(in++) = '\0'; 638 if (j == 0) 639 break; 640 if ((j >= '0') && (j <= '9')) 641 j -= '0'; 642 else if ((j >= 'A') && (j <= 'F')) 643 j = j - 'A' + 10; 644 else if ((j >= 'a') && (j <= 'f')) 645 j = j - 'a' + 10; 646 else { 647 BIO_printf(bio_err, "non-hex digit\n"); 648 return (0); 649 } 650 if (i & 1) 651 out[i / 2] |= j; 652 else 653 out[i / 2] = (j << 4); 654 } 655 return (1); 656} 657