decrypt.c revision c197cb9db36685d2808c057fdbe5700734483ab2
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * CDDL HEADER START
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The contents of this file are subject to the terms of the
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Common Development and Distribution License (the "License").
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * You may not use this file except in compliance with the License.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * See the License for the specific language governing permissions
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * and limitations under the License.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * When distributing Covered Code, include this CDDL HEADER in each
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If applicable, add the following below this CDDL HEADER, with the
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * fields enclosed by brackets "[]" replaced with your own identifying
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * information: Portions Copyright [yyyy] [name of copyright owner]
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * CDDL HEADER END
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* Portions Copyright 2005 Richard Lowe */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Use is subject to license terms.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#pragma ident "%Z%%M% %I% %E% SMI"
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Implements encrypt(1) and decrypt(1) commands
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * One binary performs both encrypt/decrypt operation.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * algorithm - mechanism name without CKM_ prefix. Case
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * does not matter
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * keyfile - file containing key data. If not specified user is
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * prompted to enter key. key length > 0 is required
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * infile - input file to encrypt/decrypt. If omitted, stdin used.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * outfile - output file to encrypt/decrypt. If omitted, stdout used.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * if infile & outfile are same, a temp file is used for
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * output and infile is replaced with this file after
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * operation is complete.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Implementation notes:
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * iv data - It is generated by random bytes equal to one block size.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * encrypted output format -
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * - Output format version number - 4 bytes in network byte order.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * - Iterations used in key gen function, 4 bytes in network byte order.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * - IV ( 'ivlen' bytes)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * - Salt data used in key gen (16 bytes)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * - cipher text data.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define BUFFERSIZE (2048) /* Buffer size for reading file */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define BLOCKSIZE (128) /* Largest guess for block size */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define PROGRESSSIZE (BUFFERSIZE*20) /* stdin progress indicator size */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Exit Status codes
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define EXIT_FAILURE 1 /* All errors except usage */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#endif /* EXIT_SUCCESS */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define RANDOM_DEVICE "/dev/urandom" /* random device name */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define ENCRYPT_NAME "encrypt" /* name of encrypt command */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define ENCRYPT_OPTIONS "a:T:K:k:i:o:lv" /* options for encrypt */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define DECRYPT_NAME "decrypt" /* name of decrypt command */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define DECRYPT_OPTIONS "a:T:K:k:i:o:lv" /* options for decrypt */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define DEFAULT_TOKEN_PROMPT "Enter PIN for %s: "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Structure containing info for encrypt/decrypt
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* function pointers for various operations */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang CK_RV (*Init)(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang CK_RV (*Update)(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang CK_RV (*Crypt)(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang CK_RV (*Final)(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang { CKM_AES_CBC_PAD, "aes", ULONG_MAX, 0L, 8, 16, B_FALSE },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang { CKM_RC4, "arcfour", ULONG_MAX, 0L, 1, 0, B_FALSE },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang { CKM_DES_CBC_PAD, "des", 8, 8, 8, 8, B_FALSE },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang { CKM_DES3_CBC_PAD, "3des", 24, 24, 8, 8, B_FALSE },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic boolean_t aflag = B_FALSE; /* -a <algorithm> flag, required */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic boolean_t kflag = B_FALSE; /* -k <keyfile> flag */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic boolean_t iflag = B_FALSE; /* -i <infile> flag, use stdin if absent */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic boolean_t oflag = B_FALSE; /* -o <outfile> flag, use stdout if absent */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic boolean_t lflag = B_FALSE; /* -l flag (list) */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic boolean_t vflag = B_FALSE; /* -v flag (verbose) */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *keyfile = NULL; /* name of keyfile */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *inputfile = NULL; /* name of input file */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *outputfile = NULL; /* name of output file */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int status_pos = 0; /* current position of progress bar element */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * function prototypes
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int execute_cmd(struct CommandInfo *cmd, char *algo_str);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int cryptogetdata(char *, CK_BYTE_PTR *pkeydata, CK_ULONG_PTR pkeysize);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int cryptoreadfile(char *filename, CK_BYTE_PTR *pdata,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int get_random_data(CK_BYTE_PTR pivbuf, int ivlen);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int crypt_multipart(struct CommandInfo *cmd, CK_SESSION_HANDLE hSession,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang extern char *optarg;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang char c; /* current getopts flag */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#if !defined(TEXT_DOMAIN) /* Should be defiend by cc -D */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Based on command name, determine
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * type of command.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang } else if (strcmp(cmdname, decrypt_cmd.name) == 0) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "command name must be either encrypt or decrypt"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Parse command line arguments */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang while (!errflag && (c = getopt(argc, argv, optstr)) != -1) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang switch (c) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (errflag || (!aflag && !lflag) || (lflag && argc > 2) ||
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * usage message
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) fprintf(stderr, gettext(" encrypt -l\n"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) fprintf(stderr, gettext(" encrypt -a <algorithm> "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "[-v] [-k <keyfile> | -K <keylabel> [-T <tokenspec>]] "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "[-i <infile>] [-o <outfile>]\n"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) fprintf(stderr, gettext(" decrypt -l\n"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) fprintf(stderr, gettext(" decrypt -a <algorithm> "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "[-v] [-k <keyfile> | -K <keylabel> [-T <tokenspec>]] "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "[-i <infile>] [-o <outfile>]\n"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Print out list of algorithms in default and verbose mode
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) printf(gettext("Algorithm Keysize: Min Max (bits)\n"
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "------------------------------------------\n"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang for (mech = 0; mech < MECH_ALIASES_COUNT; mech++) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) printf("%-15s", mech_aliases[mech].alias);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (mech_aliases[mech].keysize_min != UINT_MAX &&
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang CK_BYTE *pkeydata, /* user entered passphrase */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang CK_ULONG keylen, /* desired length of generated key */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * This function will login into the token with the provided password and
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * find the token key object with the specified keytype and keylabel.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangget_token_key(CK_SESSION_HANDLE hSession, CK_KEY_TYPE keytype,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang char *keylabel, CK_BYTE *password, int password_len,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang rv = C_Login(hSession, CKU_USER, (CK_UTF8CHAR_PTR)password,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) fprintf(stderr, "Cannot login to the token."
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang rv = C_FindObjects(hSession, keyobj, 1, &key_obj_count);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "Cannot retrieve key object. error = %s\n",
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) fprintf(stderr, "Cannot find the key object.\n");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Execute the command.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * cmd - command pointing to type of operation.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * algo_str - alias of the algorithm passed.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangexecute_cmd(struct CommandInfo *cmd, char *algo_str)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang int outfd = 1; /* output file, stdout default */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang boolean_t inoutsame = B_FALSE; /* if both input & output are same */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Determine if algorithm is valid */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang for (mech_match = 0; mech_match < MECH_ALIASES_COUNT;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Process keyfile or get the token pin if -K is specified.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If a keyfile is provided, get the key data from
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * the file. Otherwise, prompt for a passphrase. The
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * passphrase is used as the key data.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* get the pin of the token */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (token_label == NULL || !strlen(token_label)) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang } else if (kflag) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* get the key file */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang status = cryptoreadfile(keyfile, &pkeydata, &keysize);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* get the key from input */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang status = cryptogetdata(NULL, &pkeydata, &keysize);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Initialize pkcs */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang cryptoerror(LOG_STDERR, gettext("failed to initialize "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "PKCS #11 framework: %s"), pkcs11_strerror(rv));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Get slot count */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to find any cryptographic provider,"
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "please check with your system administrator: %s"),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Found at least one slot, allocate memory for slot list */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang cryptoerror(LOG_STDERR, gettext("malloc: %s"), strerror(err));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Get the list of slots */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if ((rv = C_GetSlotList(0, pSlotList, &slotcount)) != CKR_OK) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to find any cryptographic provider,"
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "please check with your system administrator: %s"),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Iterate through slots */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Iterate through each mechanism */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang for (mek = 0; mek < MECH_ALIASES_COUNT; mek++) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Set to minimum/maximum key sizes assuming
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * the values available are not 0.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Find a slot with matching mechanism
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If -K is specified, we find the slot id for the token first, then
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * check if the slot supports the algorithm.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang kmfrv = KMF_PK11TokenLookup(NULL, token_label, &token_slot_id);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang rv = C_GetMechanismInfo(token_slot_id, mech_type, &info);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang for (i = 0; i < slotcount; i++) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang rv = C_GetMechanismInfo(slotID, mech_type, &info);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang continue; /* to the next slot */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If the slot support the crypto, also
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * make sure it supports the correct
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * key generation mech if needed.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * We need PKCS5 when RC4 is used or
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * when the key is entered on cmd line.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Show error if no matching mechanism found */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Open a session */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Generate IV data for encrypt.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "Unable to generate random "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "data for initialization vector."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Create the key object
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang gettext("unable to find key type for algorithm."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Open input file */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if ((infd = open(inputfile, O_RDONLY | O_NONBLOCK)) == -1) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Get info on input file */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Prepare output file
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If the input & output file are same,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * the output is written to a temp
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * file first, then renamed to the original file
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * after the crypt operation
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* create temp file on same dir */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "cannot create temp file"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Create file for output */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "cannot open output file %s"),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Read the version number from the head of the file
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * to know how to interpret the data that follows.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to get format version from "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "input file."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* convert to host byte order */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Version 1 output format:
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * - Iterations used in key gen function (4 bytes)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * - IV ( 'ivlen' bytes)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * - Salt data used in key gen (16 bytes)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * An encrypted file has IV as first block (0 or
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * more bytes depending on mechanism) followed
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * by cipher text. Get the IV from the encrypted
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Read iteration count and salt data.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to get iterations from "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "input file."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* convert to host byte order */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to get initialization "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "vector from input file."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang != sizeof (salt)) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to get salt data from "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "input file."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "Unrecognized format version read from "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "input file - expected %d, got %d."),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If Kflag is set, let's find the token key now.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If Kflag is not set and if encrypting, we need some random
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * salt data to create the key. If decrypting,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * the salt should come from head of the file
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * to be decrypted.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang rv = get_token_key(hSession, keytype, key_label, pkeydata,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "Can not find the token key"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "data for key salt."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If key input is read from a file, treat it as
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * raw key data, unless it is to be used with RC4,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * in which case it must be used to generate a pkcs5
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * key to address security concerns with RC4 keys.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (kflag && keyfile != NULL && keytype != CKK_RC4) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang template[nattr].ulValueLen = sizeof (truevalue);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang template[nattr].ulValueLen = sizeof (falsevalue);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If the encryption type has a fixed key length,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * then its not necessary to set the key length
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * parameter when generating the key.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Generate a cryptographically secure key using
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * the key read from the file given (-k keyfile) or
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * the passphrase entered by the user.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to generate a key: %s"),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Setup up mechanism */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if ((rv = cmd->Init(hSession, &mech, key)) != CKR_OK) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to initialize crypto operation: %s"),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Write the version header encrypt command */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* convert to network order for storage */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (write(outfd, &netversion, sizeof (netversion))
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang != sizeof (netversion)) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to write version number "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "to output file."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Write the iteration and salt data, even if they
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * were not used to generate a key.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to write iterations to output"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to write initialization vector "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "to output"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (write(outfd, salt, sizeof (salt)) != sizeof (salt)) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to write salt data to output"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (crypt_multipart(cmd, hSession, infd, outfd, insbuf.st_size) == -1) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Clear the key data, so others cannot snoop */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Destroy key object */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (Kflag != B_FALSE && key != (CK_OBJECT_HANDLE) 0) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* free allocated memory */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* close all the files */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* rename tmp output to input file */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang cryptoerror(LOG_STDERR, gettext("rename failed."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* If error occurred, remove the output file */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* close pkcs11 session */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Function for printing progress bar when the verbose flag
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The vertical bar is printed at 25, 50, and 75% complete.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The function is passed the number of positions on the screen it needs to
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * advance and loops.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Encrypt/Decrypt in multi part.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * This function reads the input file (infd) and writes the
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * encrypted/decrypted output to file (outfd).
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * cmd - pointing to commandinfo
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * hSession - pkcs session
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * infd - input file descriptor
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * outfd - output file descriptor
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangcrypt_multipart(struct CommandInfo *cmd, CK_SESSION_HANDLE hSession,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang CK_ULONG status_index = 0; /* current total file size read */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang float status_last = 0.0; /* file size of last element used */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang float status_incr = 0.0; /* file size element increments */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang int pos; /* # of progress bar elements to be print */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Divide into 79 increments for progress bar element spacing */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang while ((nread = read(infd, databuf, datalen)) > 0) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Start with the initial buffer */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang rv = cmd->Update(hSession, databuf, (CK_ULONG)nread,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Need a bigger buffer? */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* free the old buffer */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* allocate a new big buffer */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if ((resultbuf = malloc((size_t)resultlen)) == NULL) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Try again with bigger buffer */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang rv = cmd->Update(hSession, databuf, (CK_ULONG)nread,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "crypto operation failed: %s"),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* write the output */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (write(outfd, resultbuf, resultlen) != resultlen) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to write result to output file."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If input is from stdin, do a our own progress bar
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * by printing periods at a pre-defined increment
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * until the file is done.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Print at least 1 element in case the file
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * is small, it looks better than nothing.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Calculate the number of elements need to be print */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Add progress bar elements, if needed */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Print verbose completion */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) fprintf(stderr, "\n%s\n", gettext("Done."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Error in reading */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "error reading from input file"));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Do the final part */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang rv = cmd->Final(hSession, resultbuf, &resultlen);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* write the output */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (write(outfd, resultbuf, resultlen) != resultlen) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "failed to write result to output file."));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "crypto operation failed: %s"),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * cryptoreadfile - reads file into a buffer
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * This function can be used for reading files
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * containing key or initialization vector data.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * filename - name of file
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * pdata - entire file returned in this buffer
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * must be freed by caller using free()
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * pdatalen - length of data returned
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * returns 0 if success, -1 if error
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangcryptoreadfile(char *filename, CK_BYTE_PTR *pdata, CK_ULONG_PTR pdatalen)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* read the file into a buffer */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) == -1) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* allocate a buffer to hold the entire key */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang cryptoerror(LOG_STDERR, gettext("malloc: %s"), strerror(err));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang cryptoerror(LOG_STDERR, gettext("error reading file: %s"),
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * cryptogetdata - prompt user for a key or the PIN for a token
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * pdata - buffer for returning key or pin data
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * must be freed by caller using free()
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * psize - size of buffer returned
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 0 for success, -1 for failure
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangcryptogetdata(char *token_spec, CK_BYTE_PTR *pdata, CK_ULONG_PTR psize)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang (void) memset(tmpbuf, 0, strlen(tmpbuf)); /* clean up */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * get_random_data - generate initialization vector data
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * iv data is random bytes
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * hSession - a pkcs session
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * pivbuf - buffer where data is returned
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * ivlen - size of iv data
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* nothing to generate */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* Read random data directly from /dev/random */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if ((fd = open(RANDOM_DEVICE, O_RDONLY)) != -1) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (-1);