void SoftapController::generatePsk(char *ssid, char *passphrase, char *psk_str) { unsigned char psk[SHA256_DIGEST_LENGTH]; int j; // Use the PKCS#5 PBKDF2 with 4096 iterations PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase), reinterpret_cast<const unsigned char *>(ssid), strlen(ssid), 4096, SHA256_DIGEST_LENGTH, psk); for (j=0; j < SHA256_DIGEST_LENGTH; j++) { sprintf(&psk_str[j*2], "%02x", psk[j]); } }
static int generate_master_key (char *passwd, char *key) { unsigned char salt[16]; if (!(RAND_bytes (salt, sizeof (salt)))) { fprintf (stderr, "Call to %s failed\n", __func__); return 0; /* 0 designates error here */ } return (PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen (passwd), (unsigned char *) salt, strlen (salt), ITERATION, KEYLEN, key)); }
/* * Arguments: * argv[2] - interface name * argv[3] - AP or P2P or STA */ int SoftapController::fwReloadSoftap(int argc, char *argv[]) { int i = 0; char *iface; char *fwpath = NULL; if (mSock < 0) { ALOGE("Softap fwrealod - failed to open socket"); return ResponseCode::OperationFailed; } if (argc < 4) { ALOGE("SoftAP fwreload is missing arguments. Please use: softap <wlan iface> <AP|P2P|STA>"); return ResponseCode::CommandSyntaxError; } iface = argv[2]; if (strcmp(argv[3], "AP") == 0) { fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP); } else if (strcmp(argv[3], "P2P") == 0) { fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_P2P); } else if (strcmp(argv[3], "STA") == 0) { fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA); } if (!fwpath) return ResponseCode::CommandParameterError; #ifdef HAVE_HOSTAPD if (wifi_change_fw_path((const char *)fwpath)) { #else sprintf(mBuf, "FW_PATH=%s", fwpath); if (setCommand(iface, "WL_FW_RELOAD")) { #endif ALOGE("Softap fwReload failed"); return ResponseCode::OperationFailed; } else { ALOGD("Softap fwReload - Ok"); } return ResponseCode::SoftapStatusResult; } void SoftapController::generatePsk(char *ssid, char *passphrase, char *psk_str) { unsigned char psk[SHA256_DIGEST_LENGTH]; int j; // Use the PKCS#5 PBKDF2 with 4096 iterations PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase), reinterpret_cast<const unsigned char *>(ssid), strlen(ssid), 4096, SHA256_DIGEST_LENGTH, psk); for (j=0; j < SHA256_DIGEST_LENGTH; j++) { sprintf(&psk_str[j*2], "%02x", psk[j]); } }
/** * derive a key from the password */ EXPORT void cryptoshit_secrete_key(char *password, void *keyOut, size_t keyOutSz) { int status = -1; const char *salt = "f**k the patriarchy"; // do the things status = PKCS5_PBKDF2_HMAC_SHA1(password, -1, (unsigned char *) salt, strlen(salt), 5000, keyOutSz, keyOut); // test??? if(status != 1) { secreteLibSSLError(); } }
int main(void) { unsigned char out[20]; int iterations = 1 << 22; PKCS5_PBKDF2_HMAC_SHA1("password", 8, (const unsigned char *) "saltsalt", 8, iterations, (int) sizeof(out), out); printf("SHA1,%d,", iterations); for (int i = 0; i < sizeof out; i++) printf("%02x", out[i]); printf("\n"); return 0; }
int unwrap_v1_header(char *passphrase, cencrypted_v1_header *header, uint8_t *aes_key, uint8_t *hmacsha1_key) { /* derived key is a 3DES-EDE key */ uint8_t derived_key[192/8]; PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase), (unsigned char*)header->kdf_salt, 20, PBKDF2_ITERATION_COUNT, sizeof(derived_key), derived_key); if (apple_des3_ede_unwrap_key(header->wrapped_aes_key, 40, derived_key, aes_key) != 0) return(-1); if (apple_des3_ede_unwrap_key(header->wrapped_hmac_sha1_key, 48, derived_key, hmacsha1_key) != 0) return(-1); return(0); }
static int pbkdf2_encrypt( const struct berval *scheme, const struct berval *passwd, struct berval *msg, const char **text) { unsigned char salt_value[PBKDF2_SALT_SIZE]; struct berval salt; unsigned char dk_value[PBKDF2_DK_SIZE]; struct berval dk; int iteration = PBKDF2_ITERATION; dk.bv_val = (char *)dk_value; dk.bv_len = PBKDF2_DK_SIZE; salt.bv_val = (char *)salt_value; salt.bv_len = sizeof(salt_value); if(lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0){ return LUTIL_PASSWD_ERR; } if(!PKCS5_PBKDF2_HMAC_SHA1(passwd->bv_val, passwd->bv_len, (unsigned char *)salt.bv_val, salt.bv_len, iteration, PBKDF2_DK_SIZE, dk_value)){ return LUTIL_PASSWD_ERR; } #ifdef SLAPD_PBKDF2_DEBUG printf("DEBUG pbkdf2_encrypt()\n"); printf(" Password:\t%s\n", passwd->bv_val); printf(" Salt:\t\t"); int i; for(i=0; i<salt.bv_len; i++){ printf("%02x", salt_value[i]); } printf("\n"); printf(" Iteration:\t%d\n", iteration); printf(" DK:\t\t"); for(i=0; i<PBKDF2_DK_SIZE; i++){ printf("%02x", dk_value[i]); } printf("\n"); #endif return pbkdf2_format(scheme, iteration, &salt, &dk, msg); }
bool GenerateKeys(const unsigned char *password, int plen, unsigned char *aesSalt, unsigned char *aesKey, unsigned char *aesIV){ if (RAND_bytes(aesSalt, SALT_LEN) == 0) return false; aesSalt[SALT_LEN] = '\0'; if (RAND_bytes(aesIV, EVP_MAX_IV_LENGTH) == 0) return false; aesIV[EVP_MAX_IV_LENGTH] = '\0'; if (PKCS5_PBKDF2_HMAC_SHA1(password, AES_KEY_LEN, aesSalt, PKCS5_SALT_LEN, ITERATIONS, AES_KEY_LEN, aesKey) == 0) return false; return true; }
/** * @brief derive the cryptographic key and IV for a given (Elektra) Key k * @param config KeySet holding the plugin/backend configuration * @param errorKey holds an error description in case of failure * @param masterKey holds the decrypted master password from the plugin configuration * @param k the (Elektra)-Key to be encrypted * @param cKey (Elektra)-Key holding the cryptographic material * @param cIv (Elektra)-Key holding the initialization vector * @retval -1 on failure. errorKey holds the error description. * @retval 1 on success */ static int getKeyIvForEncryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv) { kdb_octet_t salt[ELEKTRA_CRYPTO_DEFAULT_SALT_LEN] = { 0 }; kdb_octet_t keyBuffer[KEY_BUFFER_SIZE] = { 0 }; char * saltHexString = NULL; ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL"); // generate the salt pthread_mutex_lock (&mutex_ssl); if (!RAND_bytes (salt, ELEKTRA_CRYPTO_DEFAULT_SALT_LEN - 1)) { ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey, "failed to generate random salt with error code %lu", ERR_get_error ()); pthread_mutex_unlock (&mutex_ssl); return -1; } pthread_mutex_unlock (&mutex_ssl); saltHexString = ELEKTRA_PLUGIN_FUNCTION (ELEKTRA_PLUGIN_NAME_C, base64Encode) (salt, sizeof (salt)); if (!saltHexString) { ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed"); return -1; } keySetMeta (k, ELEKTRA_CRYPTO_META_SALT, saltHexString); elektraFree (saltHexString); // read iteration count const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config); // generate/derive the cryptographic key and the IV pthread_mutex_lock (&mutex_ssl); if (!PKCS5_PBKDF2_HMAC_SHA1 (keyValue (masterKey), keyGetValueSize (masterKey), salt, sizeof (salt), iterations, KEY_BUFFER_SIZE, keyBuffer)) { ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey, "Failed to create a cryptographic key for encryption. Libcrypto returned error code: %lu", ERR_get_error ()); pthread_mutex_unlock (&mutex_ssl); return -1; } pthread_mutex_unlock (&mutex_ssl); keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_SSL_KEYSIZE); keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_SSL_KEYSIZE, ELEKTRA_CRYPTO_SSL_BLOCKSIZE); return 1; }
/* function assumes that header is a pointer to an allocated but un-initialized setec_astronomy_header struct */ void create_header(struct setec_astronomy_header * header, int iv_len, int salt_len, int hash_count, const char * password, int hash_len) { int err; header->salt_len = salt_len; init_random_buffer(&(header->salt), header->salt_len); header->hash_count = hash_count; header->hash_len = hash_len; header->hash = malloc(header->hash_len); err = PKCS5_PBKDF2_HMAC_SHA1(password, strlen(password), header->salt, header->salt_len, header->hash_count*2, header->hash_len, header->hash); header->iv_len = iv_len; init_random_buffer(&(header->iv), header->iv_len); }
static void codec_prepare_key(sqlite3 *db, const void *zKey, int nKey, void *salt, int nSalt, void *out, int *nOut) { /* if key data lenth is exactly 256 bits / 32 bytes use the data directly */ if (nKey == 67 && sqlite3StrNICmp(zKey ,"x'", 2) == 0) { int n = nKey - 3; /* adjust for leading x' and tailing ' */ int half_n = n/2; const char *z = zKey + 2; /* adjust lead offset of x' */ void *key = sqlite3HexToBlob(db, z, n); memcpy(out, key, half_n); *nOut = half_n; memset(key, 0, half_n); /* cleanup temporary key data */ sqlite3DbFree(db, key); /* otherwise the key is provided as a string so hash it to get key data */ } else { *nOut = KEY_LENGTH; PKCS5_PBKDF2_HMAC_SHA1(zKey, nKey, salt, nSalt, PBKDF2_ITER, KEY_LENGTH, out); } }
int test_read_header() { struct setec_astronomy_header r_header; unsigned char * hash; /* Start off with a good test */ init_header(&r_header); test_equals(read_header(&r_header, GOOD_HEADER_TEST), SA_SUCCESS); /* Check to make sure that the read and write headers are identical */ test_equals(r_header.salt_len, DEFAULT_SALT_LEN); test_equals(r_header.hash_count, DEFAULT_HASH_COUNT); test_equals(r_header.hash_len, DEFAULT_HASH_LEN); test_equals(r_header.iv_len, DEFAULT_IV_LEN); hash = malloc(r_header.hash_len); PKCS5_PBKDF2_HMAC_SHA1(DEFAULT_PASSWORD, strlen(DEFAULT_PASSWORD), r_header.salt, r_header.salt_len, r_header.hash_count*2, r_header.hash_len, hash); test_equals(memcmp(r_header.hash, hash, r_header.hash_len), 0); free(hash); free_header(&r_header); /* Now try to read a header from a file that doesn't exist */ init_header(&r_header); test_equals(read_header(&r_header, "thisfiledoesntexists"), SA_FILE_NOT_FOUND); free_header(&r_header); /* Test against a file that exists but has no data */ init_header(&r_header); test_equals(read_header(&r_header, NO_DATA_TEST), SA_NO_DATA); free_header(&r_header); /* Test against a file that exists and has some but not enough data */ init_header(&r_header); test_equals(read_header(&r_header, NOT_ENOUGH_DATA_TEST), SA_NO_DATA); free_header(&r_header); return UT_SUCCESS; }
/** * @brief Create a key from the given passphrase. By default, the PBKDF2 * algorithm is used to generate the key from the passphrase. It is expected * that the same pass phrase will generate the same key, regardless of the * backend crypto platform used. The key is cleaned up when the context * is cleaned, and may be reused with multiple encryption or decryption * operations. * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If * *key is not NULL, *key must point at a previously created structure. * @param key The key returned, see note. * @param ivSize The size of the initialisation vector will be returned, based * on whether an IV is relevant for this type of crypto. * @param pass The passphrase to use. * @param passLen The passphrase length in bytes * @param salt The salt to use. * @param saltLen The salt length in bytes * @param type 3DES_192, AES_128, AES_192, AES_256. * @param mode Electronic Code Book / Cipher Block Chaining. * @param doPad Pad if necessary. * @param iterations Iteration count * @param f The context to use. * @param p The pool to use. * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend * error occurred while generating the key. APR_ENOCIPHER if the type or mode * is not supported by the particular backend. APR_EKEYTYPE if the key type is * not known. APR_EPADDING if padding was requested but is not supported. * APR_ENOTIMPL if not implemented. */ static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, const char *pass, apr_size_t passLen, const unsigned char * salt, apr_size_t saltLen, const apr_crypto_block_key_type_e type, const apr_crypto_block_key_mode_e mode, const int doPad, const int iterations, const apr_crypto_t *f, apr_pool_t *p) { apr_crypto_key_t *key = *k; apr_status_t rv; if (!key) { *k = key = apr_pcalloc(p, sizeof *key); if (!key) { return APR_ENOMEM; } } key->f = f; key->provider = f->provider; /* decide on what cipher mechanism we will be using */ rv = crypto_cipher_mechanism(key, type, mode, doPad, p); if (APR_SUCCESS != rv) { return rv; } /* generate the key */ if (PKCS5_PBKDF2_HMAC_SHA1(pass, passLen, (unsigned char *) salt, saltLen, iterations, key->keyLen, key->key) == 0) { return APR_ENOKEY; } key->doPad = doPad; /* note: openssl incorrectly returns non zero IV size values for ECB * algorithms, so work around this by ignoring the IV size. */ if (APR_MODE_ECB != mode) { key->ivSize = EVP_CIPHER_iv_length(key->cipher); } if (ivSize) { *ivSize = key->ivSize; } return APR_SUCCESS; }
/* * call-seq: * PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string * * === Parameters * * +pass+ - string * * +salt+ - string * * +iter+ - integer - should be greater than 1000. 2000 is better. * * +keylen+ - integer * * This method is available almost any version OpenSSL. * * Conforms to rfc2898. */ static VALUE ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen) { VALUE str; int len = NUM2INT(keylen); StringValue(pass); StringValue(salt); str = rb_str_new(0, len); if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass), (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter), len, (unsigned char *)RSTRING_PTR(str)) != 1) ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1"); return str; }
/** * Derive an encryption key for a cipher contex key based on the raw password. * * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill * the key space (i.e 64 hex chars for a 256 bit key) then the key data will be used directly. * * Otherwise, a key data will be derived using PBKDF2 * * returns SQLITE_OK if initialization was successful * returns SQLITE_NOMEM if the key could't be derived (for instance if pass is NULL or pass_sz is 0) */ static int codec_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) { CODEC_TRACE(("codec_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d ctx->kdf_salt=%d ctx->kdf_salt_sz=%d c_ctx->kdf_iter=%d c_ctx->key_sz=%d\n", c_ctx->pass, c_ctx->pass_sz, ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter, c_ctx->key_sz)); if(c_ctx->pass && c_ctx->pass_sz) { // if pass is not null if (c_ctx->pass_sz == ((c_ctx->key_sz*2)+3) && sqlite3StrNICmp(c_ctx->pass ,"x'", 2) == 0) { int n = c_ctx->pass_sz - 3; /* adjust for leading x' and tailing ' */ const char *z = c_ctx->pass + 2; /* adjust lead offset of x' */ CODEC_TRACE(("codec_key_derive: deriving key from hex\n")); cipher_hex2bin(z, n, c_ctx->key); } else { CODEC_TRACE(("codec_key_derive: deriving key using PBKDF2\n")); PKCS5_PBKDF2_HMAC_SHA1(c_ctx->pass, c_ctx->pass_sz, ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter, c_ctx->key_sz, c_ctx->key); } return SQLITE_OK; }; return SQLITE_ERROR; }
static void db_pwhash(sqlite3_context *context, int argc, sqlite3_value **argv){ int res; assert( argc==2 ); assert( sqlite3_value_type(argv[0]) == SQLITE_BLOB ); assert( sqlite3_value_type(argv[1]) == SQLITE3_TEXT ); const int saltsize = sqlite3_value_bytes(argv[0]); const unsigned char *salt = sqlite3_value_blob(argv[0]); const int pwsize = sqlite3_value_bytes(argv[1]); const unsigned char *pw = sqlite3_value_blob(argv[1]); unsigned char *out = calloc(sizeof (unsigned char), DB_PWHASH_OUTLEN); res = PKCS5_PBKDF2_HMAC_SHA1((const char *)pw, pwsize, salt, saltsize, DB_PWHASH_ITERS, DB_PWHASH_OUTLEN, out); assert(res != 0); sqlite3_result_blob(context, out, DB_PWHASH_OUTLEN, free); }
K pbkdf2(K qpassword,K qsalt,K qiterations, K qdklen){ int iterations,dklen,passlen,saltlen,i,retv; passlen=qpassword->n; saltlen=qsalt->n; char password[passlen]; unsigned char salt[saltlen]; iterations=qiterations->i; dklen=qdklen->i; unsigned char result[dklen]; if(10==(qpassword->t)){ for(i=0;i<passlen;i++){ password[i]=kC(qpassword)[i]; } password[passlen]=0; } if(4==(qsalt->t)){ for(i=0;i<saltlen;i++){ salt[i]=kG(qsalt)[i]; } } retv=PKCS5_PBKDF2_HMAC_SHA1(password,strlen(password),salt,sizeof(salt),iterations,dklen,result); if(retv==0){ krr("PKCS5_PBKDF2_HMAC_SHA1 failed"); return (K)0; } K output=ktn(KG,dklen); for(i=0;i<dklen;i++){ kG(output)[i]=result[i]; } return output; }
/** * @brief Create a key from the given passphrase. By default, the PBKDF2 * algorithm is used to generate the key from the passphrase. It is expected * that the same pass phrase will generate the same key, regardless of the * backend crypto platform used. The key is cleaned up when the context * is cleaned, and may be reused with multiple encryption or decryption * operations. * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If * *key is not NULL, *key must point at a previously created structure. * @param key The key returned, see note. * @param ivSize The size of the initialisation vector will be returned, based * on whether an IV is relevant for this type of crypto. * @param pass The passphrase to use. * @param passLen The passphrase length in bytes * @param salt The salt to use. * @param saltLen The salt length in bytes * @param type 3DES_192, AES_128, AES_192, AES_256. * @param mode Electronic Code Book / Cipher Block Chaining. * @param doPad Pad if necessary. * @param iterations Iteration count * @param f The context to use. * @param p The pool to use. * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend * error occurred while generating the key. APR_ENOCIPHER if the type or mode * is not supported by the particular backend. APR_EKEYTYPE if the key type is * not known. APR_EPADDING if padding was requested but is not supported. * APR_ENOTIMPL if not implemented. */ static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, const char *pass, apr_size_t passLen, const unsigned char * salt, apr_size_t saltLen, const apr_crypto_block_key_type_e type, const apr_crypto_block_key_mode_e mode, const int doPad, const int iterations, const apr_crypto_t *f, apr_pool_t *p) { apr_crypto_key_t *key = *k; if (!key) { *k = key = apr_array_push(f->keys); } if (!key) { return APR_ENOMEM; } key->f = f; key->provider = f->provider; /* determine the cipher to be used */ switch (type) { case (APR_KEY_3DES_192): /* A 3DES key */ if (mode == APR_MODE_CBC) { key->cipher = EVP_des_ede3_cbc(); } else { key->cipher = EVP_des_ede3_ecb(); } break; case (APR_KEY_AES_128): if (mode == APR_MODE_CBC) { key->cipher = EVP_aes_128_cbc(); } else { key->cipher = EVP_aes_128_ecb(); } break; case (APR_KEY_AES_192): if (mode == APR_MODE_CBC) { key->cipher = EVP_aes_192_cbc(); } else { key->cipher = EVP_aes_192_ecb(); } break; case (APR_KEY_AES_256): if (mode == APR_MODE_CBC) { key->cipher = EVP_aes_256_cbc(); } else { key->cipher = EVP_aes_256_ecb(); } break; default: /* unknown key type, give up */ return APR_EKEYTYPE; } /* find the length of the key we need */ key->keyLen = EVP_CIPHER_key_length(key->cipher); /* make space for the key */ key->key = apr_pcalloc(p, key->keyLen); if (!key->key) { return APR_ENOMEM; } apr_crypto_clear(p, key->key, key->keyLen); /* generate the key */ if (PKCS5_PBKDF2_HMAC_SHA1(pass, passLen, (unsigned char *) salt, saltLen, iterations, key->keyLen, key->key) == 0) { return APR_ENOKEY; } key->doPad = doPad; /* note: openssl incorrectly returns non zero IV size values for ECB * algorithms, so work around this by ignoring the IV size. */ if (APR_MODE_ECB != mode) { key->ivSize = EVP_CIPHER_iv_length(key->cipher); } if (ivSize) { *ivSize = key->ivSize; } return APR_SUCCESS; }
static int sqlcipher_openssl_kdf(void *ctx, const char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) { PKCS5_PBKDF2_HMAC_SHA1(pass, pass_sz, salt, salt_sz, workfactor, key_sz, key); return SQLITE_OK; }
unsigned char *rncryptorc_decrypt_data_with_password(const unsigned char *indata, int indata_len, int kdf_iter, const char *password, int password_length, int *outdata_len, char *errbuf, int errbuf_len) { MutilsBlob *blob = NULL; RNCryptorInfo *ci = NULL; int rc, outlen1=0, outlen2=0; EVP_CIPHER_CTX cipher_ctx; unsigned char *outdata = NULL; if (errbuf_len <= 0) { log_err("ERROR:Invalid errbuf len %d",errbuf_len); goto ExitProcessing; } if (indata == NULL) { (void)snprintf(errbuf,errbuf_len-1,"%s", "Input data is NULL"); goto ExitProcessing; } if (password == NULL || *password == '\0') { (void)snprintf(errbuf,errbuf_len-1,"%s", "Password is NULL"); goto ExitProcessing; } if (password_length <= 0) { (void)snprintf(errbuf,errbuf_len-1, "Invalid password length %d",password_length); goto ExitProcessing; } *outdata_len = 0; /* convert input data to our blob */ blob = mutils_data_to_blob((unsigned char *)indata,indata_len); CHECK_MALLOC(blob); /* decode */ log_debug("%s:%d - Decoding ..",MCFL); ci = decode_encrypted_blob(blob); if (!ci) { goto ExitProcessing; } ci->options = 0x01; rc = verify_rncryptor_format(ci->version,ci->options); if (rc != SUCCESS) { (void)snprintf(errbuf,errbuf_len-1,"%s", "Unknown RNCryptor Data Format"); goto ExitProcessing; } log_debug("%s:%d - Decoded version 0x%02x options 0x%02x", MCFL, ci->version, ci->options); log_debug("%s:%d - Verifying HMAC-SHA256 digest",MCFL); /* very hmac */ if (verify_hmac(ci,password,password_length) != SUCCESS) { (void)snprintf(errbuf,errbuf_len-1,"%s", "Could not verify HMAC"); goto ExitProcessing; } log_debug("%s:%d - HMAC verified",MCFL); /* Derive cipher key from password using encr salt and iteration as per RFC2898 */ log_debug("%s:%d - Deriving Cipher key with salt, iteration %d", MCFL, kdf_iter); rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length, ci->encryption_salt, sizeof(ci->encryption_salt), ci->kdf_iter, sizeof(ci->encr_key), ci->encr_key); /* ci->encr_key is returend */ if (rc != 1) { log_err("ERROR: Could not derive key from password with encr salt and iter"); goto ExitProcessing; } log_debug("%s:%d - Encryption key derived",MCFL); /* decrypt */ outdata = (unsigned char *)malloc(ci->cipher_text_length *sizeof(unsigned char)); CHECK_MALLOC(outdata); log_debug("%s:%d - Decrypting..",MCFL); EVP_DecryptInit(&cipher_ctx,EVP_aes_256_cbc(),ci->encr_key,ci->iv); EVP_DecryptUpdate(&cipher_ctx,outdata,&outlen1,ci->cipher_text, ci->cipher_text_length); EVP_DecryptFinal(&cipher_ctx,outdata + outlen1,&outlen2); EVP_CIPHER_CTX_cleanup(&cipher_ctx); *outdata_len = outlen1 + outlen2; log_debug("%s:%d - Done decrypting, output length %d bytes",MCFL,*outdata_len); ExitProcessing: if (ci) { free_rncryptor_info(ci); } if (blob) { mutils_destroy_blob(blob); } return(outdata); }
/* RFC 5802: Salted Challenge Response Authentication Mechanism Note: SCRAM is a client-first SASL mechanism I want to thx Simon Josefsson for his public server test, and my girlfriend that let me work on that 2 whole nights ;) clientfirstmessagebare must be at least 500 bytes in size! */ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, char *serverfirstmessage) { int saltlen = 0; int iter = 4096; char *salt, *nonce, *ic; unsigned int resultlen = 0; char clientfinalmessagewithoutproof[200]; char buffer[500]; unsigned char SaltedPassword[SHA_DIGEST_LENGTH]; unsigned char ClientKey[SHA_DIGEST_LENGTH]; unsigned char StoredKey[SHA_DIGEST_LENGTH]; unsigned char ClientSignature[SHA_DIGEST_LENGTH]; char AuthMessage[1024]; char ClientProof[SHA_DIGEST_LENGTH]; unsigned char clientproof_b64[50]; char *preppasswd; int rc = sasl_saslprep(pass, 0, &preppasswd); if (rc) { result = NULL; return; } /*client-final-message */ if (debug) hydra_report(stderr, "DEBUG S: %s\n", serverfirstmessage); //r=hydra28Bo7kduPpAZLzhRQiLxc8Y9tiwgw+yP,s=ldDgevctH+Kg7b8RnnA3qA==,i=4096 if (strstr(serverfirstmessage, "r=") == NULL) { hydra_report(stderr, "Error: Can't understand server message\n"); free(preppasswd); result = NULL; return; } strncpy(buffer, serverfirstmessage, sizeof(buffer) - 1); buffer[sizeof(buffer) - 1] = '\0'; nonce = strtok(buffer, ","); //continue to search from the previous successful call salt = strtok(NULL, ","); ic = strtok(NULL, ","); iter = atoi(ic + 2); if (iter == 0) { hydra_report(stderr, "Error: Can't understand server response\n"); free(preppasswd); result = NULL; return; } if ((nonce != NULL) && (strlen(nonce) > 2)) snprintf(clientfinalmessagewithoutproof, sizeof(clientfinalmessagewithoutproof), "c=biws,%s", nonce); else { hydra_report(stderr, "Error: Could not identify server nonce value\n"); free(preppasswd); result = NULL; return; } if ((salt != NULL) && (strlen(salt) > 2) && (strlen(salt) <= sizeof(buffer))) //s=ghgIAfLl1+yUy/Xl1WD5Tw== remove the header s= strcpy(buffer, salt + 2); else { hydra_report(stderr, "Error: Could not identify server salt value\n"); free(preppasswd); result = NULL; return; } /* SaltedPassword := Hi(Normalize(password), salt, i) */ saltlen = from64tobits((char *) salt, buffer); if (PKCS5_PBKDF2_HMAC_SHA1(preppasswd, strlen(preppasswd), (unsigned char *) salt, saltlen, iter, SHA_DIGEST_LENGTH, SaltedPassword) != 1) { hydra_report(stderr, "Error: Failed to generate PBKDF2\n"); free(preppasswd); result = NULL; return; } /* ClientKey := HMAC(SaltedPassword, "Client Key") */ #define CLIENT_KEY "Client Key" HMAC(EVP_sha1(), SaltedPassword, SHA_DIGEST_LENGTH, (const unsigned char *) CLIENT_KEY, strlen(CLIENT_KEY), ClientKey, &resultlen); /* StoredKey := H(ClientKey) */ SHA1((const unsigned char *) ClientKey, SHA_DIGEST_LENGTH, StoredKey); /* ClientSignature := HMAC(StoredKey, AuthMessage) */ snprintf(AuthMessage, 500, "%s,%s,%s", clientfirstmessagebare, serverfirstmessage, clientfinalmessagewithoutproof); HMAC(EVP_sha1(), StoredKey, SHA_DIGEST_LENGTH, (const unsigned char *) AuthMessage, strlen(AuthMessage), ClientSignature, &resultlen); /* ClientProof := ClientKey XOR ClientSignature */ xor(ClientProof, (char *) ClientKey, (char *) ClientSignature, 20); to64frombits(clientproof_b64, (const unsigned char *) ClientProof, 20); snprintf(result, 500, "%s,p=%s", clientfinalmessagewithoutproof, clientproof_b64); if (debug) hydra_report(stderr, "DEBUG C: %s\n", result); free(preppasswd); }
unsigned char *rncryptorc_encrypt_data_with_password_with_salts_and_iv(const unsigned char *indata, int indata_len, int kdf_iter, const char *password, int password_length, unsigned char *encr_salt_8, unsigned char *hmac_salt_8, unsigned char *iv_16, int *outdata_len, char *errbuf, int errbuf_len) { RNCryptorInfo *ci = NULL; MutilsBlob *blob = NULL; EVP_CIPHER_CTX cipher_ctx; HMAC_CTX hmac_ctx; int rc=FAILURE; const EVP_MD *sha256 = NULL; int outlen1 = 0, outlen2 = 0; unsigned int hmac_len; unsigned char hmac_sha256[32]; unsigned char *output = NULL; unsigned int blocksize = 16; unsigned char *ciphertext = NULL; unsigned char encr_key[32], hmac_key[32]; int ciphertext_len; log_debug("%s:%d - verifying input",MCFL); if (errbuf_len <= 0) { log_err("ERROR:Invalid errbuf len %d",errbuf_len); goto ExitProcessing; } memset(errbuf,0,errbuf_len); memset(encr_key,0,sizeof(encr_key)); memset(hmac_key,0,sizeof(hmac_key)); if (password == NULL || *password == '\0') { (void)snprintf(errbuf,errbuf_len-1,"%s", "Password can not be NULL"); goto ExitProcessing; } if (password_length <= 0) { (void)snprintf(errbuf,errbuf_len-1,"Invalid password length %d",password_length); goto ExitProcessing; } ci = allocate_rncryptor_info(); if (!ci) { goto ExitProcessing; } ci->options = 0x01; /* Derive cipher key from password using encr salt and iteration as per RFC2898 */ log_debug("%s:%d - Deriving Cipher key with salt, iterations %d", MCFL, kdf_iter); rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length, encr_salt_8, 8, kdf_iter, 32, encr_key); /* encr_key is returend */ if (rc != 1) { log_err("ERROR: Could not derive key from password with encr salt and iter"); (void)snprintf(errbuf,errbuf_len-1,"%s", "Could not derive key from password with encr salt and iter"); goto ExitProcessing; } EVP_EncryptInit(&cipher_ctx,EVP_aes_256_cbc(),encr_key,iv_16); blocksize = EVP_CIPHER_CTX_block_size(&cipher_ctx); log_debug("%s:%d - Block size: %ld",MCFL,blocksize); if (indata == NULL && indata_len == 0) { blob = mutils_allocate_blob(blocksize); } else { blob = mutils_allocate_blob(indata_len); } CHECK_MALLOC(blob); log_debug("%s:%d - input data size %d bytes", MCFL, indata_len); log_debug("%s:%d - Encoding",MCFL); /* ** Encode. memory will be re-allocated for blob if needed. */ /* version */ mutils_write_blob_byte(blob,ci->version); /* options */ mutils_write_blob_byte(blob,ci->options); /* 8 byte encryption salt, we're using password */ mutils_write_blob(blob,8,encr_salt_8); /* 8 byte hmac salt */ mutils_write_blob(blob,8,hmac_salt_8); /* 16 byte iv */ mutils_write_blob(blob,16,iv_16); log_debug("%s:%d - Deriving HMAC key with salt, iterations %d", MCFL, kdf_iter); /* Derive HMAC key from password using hmac salt and iteration as per RFC2898 */ rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length, hmac_salt_8, 8, kdf_iter, 32, hmac_key); /* hmac_key is returend */ if (rc != 1) { log_err("ERROR: Could not derive key from password with hmac salt and iter"); (void)snprintf(errbuf,errbuf_len-1,"%s", "Could not derive key from password with hmac salt and iter"); goto ExitProcessing; } log_debug("%s:%d - Encrypting..",MCFL); /* allocate space for cipher text */ ciphertext_len = indata_len + blocksize - (indata_len % blocksize); ciphertext = (unsigned char *) malloc(ciphertext_len * sizeof(unsigned char)); CHECK_MALLOC(ciphertext); EVP_EncryptUpdate(&cipher_ctx,ciphertext,&outlen1,indata,indata_len); EVP_EncryptFinal(&cipher_ctx,ciphertext + outlen1,&outlen2); EVP_CIPHER_CTX_cleanup(&cipher_ctx); mutils_write_blob(blob,outlen1 + outlen2,ciphertext); log_debug("%s:%d - Plain text length: %d",MCFL,indata_len); log_debug("%s:%d - Cipther text length: %d",MCFL,outlen1 + outlen2); log_debug("%s:%d - Padding %d bytes", MCFL, (ciphertext_len - indata_len)); log_debug("%s:%d - outdata len: %d",MCFL,outlen1 + outlen2); log_debug("%s:%d - calculating HMAC-SHA256",MCFL); /* calculate HMAC-SHA256 */ sha256 = EVP_sha256(); HMAC_CTX_init(&hmac_ctx); HMAC_Init(&hmac_ctx,hmac_key,sizeof(hmac_key),sha256); HMAC_Update(&hmac_ctx,blob->data,blob->length); HMAC_Final(&hmac_ctx,hmac_sha256,&hmac_len); HMAC_CTX_cleanup(&hmac_ctx); mutils_write_blob(blob,hmac_len,hmac_sha256); log_debug("%s:%d - Output lenth %lu",MCFL,blob->length); output = (unsigned char *)malloc(blob->length * sizeof(unsigned char)); CHECK_MALLOC(output); memcpy(output,blob->data,blob->length); *outdata_len = blob->length; ExitProcessing: if (ci) { free_rncryptor_info(ci); } if (blob) { mutils_destroy_blob(blob); } if (ciphertext) { (void)free((char *)ciphertext); } return(output); }
/* ** returns SUCCESS or FAILRUE ** if key based encryption/decryption is used, pass ci->hmac_key, also pass ** password as NULL and length of pasword as 0 */ static int verify_hmac(RNCryptorInfo *ci,const char *password, int password_len) { unsigned char hmac_sha256[32]; const EVP_MD *sha256=NULL; HMAC_CTX hmac_ctx; unsigned int hmac_len; int rc; if (ci == NULL) { return(FAILURE); } if (password != NULL) { /* Derive hmac key from password using hmac salt and iteration as per RFC2898 */ rc = PKCS5_PBKDF2_HMAC_SHA1(password, password_len, ci->hmac_salt, sizeof(ci->hmac_salt), ci->kdf_iter, sizeof(ci->hmac_key), ci->hmac_key); /* ci->hmac_key is returend */ if (rc != 1) { log_err("ERROR: Could not derive key from password with hmac salt and iter"); goto ExitProcessing; } } else { /* caller must pass ci->hmac_key */ } /* ** calculate HMAC-SHA256 of (data-32) and compare that with the HMAC-SHA256 ** which is the last 32 bytes of the data */ sha256 = EVP_sha256(); HMAC_CTX_init(&hmac_ctx); HMAC_Init(&hmac_ctx,ci->hmac_key,32,sha256); HMAC_Update(&hmac_ctx,ci->blob->data,ci->blob->length - 32); HMAC_Final(&hmac_ctx,hmac_sha256,&hmac_len); HMAC_CTX_cleanup(&hmac_ctx); rc = memcmp(ci->hmac,hmac_sha256,32); if (rc != 0) { log_err("ERROR: Could not verify HMAC"); goto ExitProcessing; } return SUCCESS; ExitProcessing: return(FAILURE); }
unsigned char * file_data_read_encrypted(struct file *file, long long offset, int size, int size_uncomp, int compressed, char *passwd) { #ifdef HAVE_LIBCRYPTO void *ret; unsigned char *buffer = 0; uLongf destLen=size_uncomp; if (file->cache) { struct file_cache_id id={offset,size,file->name_id,1}; ret=cache_lookup(file_cache,&id); if (ret) return ret; ret=cache_insert_new(file_cache,&id,size_uncomp); } else ret=g_malloc(size_uncomp); lseek(file->fd, offset, SEEK_SET); buffer = (unsigned char *)g_malloc(size); if (read(file->fd, buffer, size) != size) { g_free(ret); ret=NULL; } else { unsigned char key[34], salt[8], verify[2], counter[16], xor[16], mac[10], *datap; int overhead=sizeof(salt)+sizeof(verify)+sizeof(mac); int esize=size-overhead; PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), (unsigned char *)buffer, 8, 1000, 34, key); if (key[32] == buffer[8] && key[33] == buffer[9] && esize >= 0) { AES_KEY aeskey; AES_set_encrypt_key(key, 128, &aeskey); datap=buffer+sizeof(salt)+sizeof(verify); memset(counter, 0, sizeof(counter)); while (esize > 0) { int i,curr_size,idx=0; do { counter[idx]++; } while (!counter[idx++]); AES_encrypt(counter, xor, &aeskey); curr_size=esize; if (curr_size > sizeof(xor)) curr_size=sizeof(xor); for (i = 0 ; i < curr_size ; i++) *datap++^=xor[i]; esize-=curr_size; } size-=overhead; datap=buffer+sizeof(salt)+sizeof(verify); if (compressed) { if (uncompress_int(ret, &destLen, (Bytef *)datap, size) != Z_OK) { dbg(0,"uncompress failed\n"); g_free(ret); ret=NULL; } } else { if (size == destLen) memcpy(ret, buffer, destLen); else { dbg(0,"memcpy failed\n"); g_free(ret); ret=NULL; } } } else { g_free(ret); ret=NULL; } } g_free(buffer); return ret; #else return NULL; #endif }
QString Nicookie::chromeDecrypt(const QByteArray &encrypt_data) { QString data; #ifdef Q_OS_WIN DATA_BLOB encrypt_data_blob; encrypt_data_blob.pbData = (BYTE*)(encrypt_data.data()); encrypt_data_blob.cbData = static_cast<DWORD>(encrypt_data.size()); DATA_BLOB plain_data_blob; BOOL result = CryptUnprotectData(&encrypt_data_blob, NULL, NULL, NULL, NULL, 0, &plain_data_blob); if (!result) { setError(Nicookie::FailedDecrytError); return QString(); } data = (QByteArray((char *)(plain_data_blob.pbData), plain_data_blob.cbData)); LocalFree(plain_data_blob.pbData); #else // O_QS_WIN #ifdef Q_OS_OSX // https://developer.apple.com/library/mac/documentation/Security/Reference/keychainservices/index.html#//apple_ref/c/func/SecKeychainFindGenericPassword UInt32 password_size = 0; void *password = NULL; OSStatus os_status; os_status = SecKeychainFindGenericPassword(NULL, 19, "Chrome Safe Storage", 6, "Chrome", &password_size, &password, NULL); if (password_size == 0) { setError(Nicookie::FailedDecrytError); SecKeychainItemFreeContent(NULL, password); return data; } #else // Q_OS_OSX int password_size = 7; void *password = (void *)"peanuts"; #endif // Q_OS_OSX const int enc_key_size = 16; unsigned char enc_key[enc_key_size]; #ifdef Q_OS_OSX int iterations = 1003; #else // Q_OS_OSX int iterations = 1; #endif // Q_OS_OSX const char *salt = "saltysalt"; int pbkdf2_r = PKCS5_PBKDF2_HMAC_SHA1((char *)password, password_size, (unsigned char *)salt, strlen(salt), iterations, enc_key_size, enc_key); if (!pbkdf2_r) { setError(Nicookie::FailedDecrytError); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } const int iv_size = 16; unsigned char iv[iv_size]; for (int i = 0; i < iv_size; i++) iv[i] = ' '; // alwayes enc size >= dec size int plain_value_size = encrypt_data.size(); char *plain_value = (char *)malloc(plain_value_size); if (plain_value == NULL) { setError(Nicookie::FailedDecrytError); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } int result = 1; EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); result = EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, enc_key, iv); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } result = EVP_DecryptUpdate(&ctx, (unsigned char *)plain_value, &plain_value_size, (unsigned char *)(encrypt_data.data() + 3), encrypt_data.size() - 3); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } int fin_size = 0; result = EVP_DecryptFinal_ex(&ctx, (unsigned char *)(plain_value + plain_value_size), &fin_size); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } EVP_CIPHER_CTX_cleanup(&ctx); plain_value[plain_value_size + fin_size] = '\0'; data = plain_value; free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX #endif // O_QS_WIN return data; }
int main(int argc, char *argv[]) { unsigned char cipher_key[CIPHER_KEY_LEN]; unsigned char hmac_key[HMAC_KEY_LEN]; unsigned char md[HMAC_LEN]; unsigned char *ciphertext; int ciphertext_len; unsigned char *plaintext; int plaintext_len; int strength; const EVP_CIPHER *cipher_type; EVP_CIPHER_CTX *ctx; FILE *fp; int len; int status; long file_size; if (argc < 5) { fprintf(stderr, "dec -- decrypt jacs-format file\n"); fprintf(stderr, "usage: dec <alg> <password> <strength> <infile> [outfile]\n"); fprintf(stderr, "algs:\n"); fprintf(stderr, " PBKDF2-SHA1-AES256-HMAC-SHA256\n"); fprintf(stderr, "password : password or 'p' to prompt from stdin without echo\n"); fprintf(stderr, "strength : key derivation complexity\n"); fprintf(stderr, "infile : input file\n"); fprintf(stderr, "outfile : output file, defaults to stdout\n"); return 2; } #ifdef USE_MLOCK /* For security, disable paging */ if (mlockall(MCL_CURRENT|MCL_FUTURE)) { fprintf(stderr, "mlockall() failed\n"); return 1; } #endif /* Initialise OpenSSL */ ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); OPENSSL_config(NULL); /* Get strength */ strength = atoi(argv[3]); if (strength < 1 || strength > 31) { fprintf(stderr, "strength must be between 1 and 31\n"); return 1; } /* Possibly read password from console */ if (!strcmp(argv[2], "p")) argv[2] = getpass("Password:"******"PKCS5_PBKDF2_HMAC_SHA1 (cipher) failed\n"); return 1; } #if DEBUG fprintf(stderr, "Cipher key: "); dump_hex(cipher_key, sizeof(cipher_key)); fprintf(stderr, "\n"); #endif /* Derive HMAC key */ status = PKCS5_PBKDF2_HMAC_SHA1(argv[2], strlen(argv[2]), hmac_salt, sizeof(hmac_salt), 1<<strength, HMAC_KEY_LEN, hmac_key); if (!status) { fprintf(stderr, "PKCS5_PBKDF2_HMAC_SHA1 (hmac) failed\n"); return 1; } #if DEBUG fprintf(stderr, "HMAC key: "); dump_hex(hmac_key, sizeof(hmac_key)); fprintf(stderr, "\n"); #endif /* Load ciphertext file into memory */ fp = fopen(argv[4], "r"); if (!fp) { fprintf(stderr, "cannot open input ciphertext file %s\n", argv[4]); return 1; } if (fseek(fp, 0L, SEEK_END)) { fprintf(stderr, "fseek failed\n"); return 1; } file_size = ftell(fp); ciphertext_len = file_size; if (file_size < 0 || file_size != (long)ciphertext_len) { fprintf(stderr, "file too large\n"); return 1; } if (fseek(fp, 0L, SEEK_SET)) { fprintf(stderr, "fseek failed\n"); return 1; } ciphertext = malloc(file_size); plaintext = malloc(file_size); if (!ciphertext || !plaintext) { fprintf(stderr, "malloc failed\n"); return 1; } if (fread(ciphertext, 1, file_size, fp) != file_size) { fprintf(stderr, "read error\n"); return 1; } if (fclose(fp)) { fprintf(stderr, "close error\n"); return 1; } /* Verify file size */ if (file_size < IV_LEN + HMAC_LEN) { fprintf(stderr, "ciphertext file is impossibly small\n"); return 1; } /* Verify HMAC */ { unsigned int md_len = HMAC_LEN; HMAC(EVP_sha256(), hmac_key, HMAC_KEY_LEN, ciphertext, ciphertext_len - HMAC_LEN, md, &md_len); if (memcmp(md, ciphertext + ciphertext_len - HMAC_LEN, HMAC_LEN) || md_len != HMAC_LEN) { fprintf(stderr, "HMAC FAILED\n"); return 1; } } /* Get cipher type */ if (!strcmp(argv[1], "PBKDF2-SHA1-AES256-HMAC-SHA256")) { cipher_type = EVP_aes_256_cbc(); } else { fprintf(stderr, "cipher type '%s' not found\n", argv[1]); return 1; } /* Decrypt */ if (!(ctx = EVP_CIPHER_CTX_new())) { fprintf(stderr, "EVP_CIPHER_CTX_new failed\n"); return 1; } if (EVP_DecryptInit_ex(ctx, cipher_type, NULL, cipher_key, ciphertext) != 1) { fprintf(stderr, "EVP_DecryptInit_ex failed\n"); return 1; } if (EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext + IV_LEN, ciphertext_len - IV_LEN - HMAC_LEN) != 1) { fprintf(stderr, "EVP_DecryptUpdate failed\n"); return 1; } plaintext_len = len; if (EVP_DecryptFinal_ex(ctx, plaintext + len, &len) != 1) { fprintf(stderr, "EVP_DecryptFinal_ex failed\n"); return 1; } plaintext_len += len; /* Write plaintext */ if (argc >= 6) { /* to file */ fp = fopen(argv[5], "w"); if (!fp) { fprintf(stderr, "cannot open output plaintext file %s\n", argv[4]); return 1; } if (fwrite(plaintext, 1, plaintext_len, fp) != plaintext_len) { fprintf(stderr, "write error\n"); return 1; } if (fclose(fp)) { fprintf(stderr, "close error\n"); return 1; } } else { /* to stdout */ if (fwrite(plaintext, 1, plaintext_len, stdout) != plaintext_len) { fprintf(stderr, "write error\n"); return 1; } } EVP_CIPHER_CTX_free(ctx); free(ciphertext); free(plaintext); return 0; }
static int string_to_key_test(krb5_context context) { krb5_data password, opaque; krb5_error_code ret; krb5_salt salt; int val = 0; char iter[4]; size_t i; for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) { password.data = keys[i].password; password.length = strlen(password.data); salt.salttype = KRB5_PW_SALT; salt.saltvalue.data = keys[i].salt; if (keys[i].saltlen == -1) salt.saltvalue.length = strlen(salt.saltvalue.data); else salt.saltvalue.length = keys[i].saltlen; opaque.data = iter; opaque.length = sizeof(iter); _krb5_put_int(iter, keys[i].iterations, 4); if (keys[i].pbkdf2) { unsigned char keyout[32]; if (keys[i].keylen > sizeof(keyout)) abort(); PKCS5_PBKDF2_HMAC_SHA1(password.data, password.length, salt.saltvalue.data, salt.saltvalue.length, keys[i].iterations, keys[i].keylen, keyout); if (memcmp(keyout, keys[i].pbkdf2, keys[i].keylen) != 0) { krb5_warnx(context, "%d: pbkdf2", (int)i); val = 1; continue; } if (verbose) { printf("PBKDF2:\n"); hex_dump_data(keyout, keys[i].keylen); } } { krb5_keyblock key; ret = krb5_string_to_key_data_salt_opaque (context, keys[i].enctype, password, salt, opaque, &key); if (ret) { krb5_warn(context, ret, "%d: string_to_key_data_salt_opaque", (int)i); val = 1; continue; } if (key.keyvalue.length != keys[i].keylen) { krb5_warnx(context, "%d: key wrong length (%lu/%lu)", (int)i, (unsigned long)key.keyvalue.length, (unsigned long)keys[i].keylen); val = 1; continue; } if (memcmp(key.keyvalue.data, keys[i].key, keys[i].keylen) != 0) { krb5_warnx(context, "%d: key wrong", (int)i); val = 1; continue; } if (verbose) { printf("key:\n"); hex_dump_data(key.keyvalue.data, key.keyvalue.length); } krb5_free_keyblock_contents(context, &key); } } return val; }
void write_zipmember(struct zip_info *zip_info, char *name, int filelen, char *data, int data_size) { struct zip_lfh lfh = { 0x04034b50, 0x0a, 0x0, 0x0, zip_info->time, zip_info->date, 0x0, 0x0, 0x0, filelen, 0x0, }; struct zip_cd cd = { 0x02014b50, 0x17, 0x00, 0x0a, 0x00, 0x0000, 0x0, zip_info->time, zip_info->date, 0x0, 0x0, 0x0, filelen, 0x0000, 0x0000, 0x0000, 0x0000, 0x0, zip_info->offset, }; struct zip_cd_ext cd_ext = { 0x1, 0x8, zip_info->offset, }; #ifdef HAVE_LIBCRYPTO struct zip_enc enc = { 0x9901, 0x7, 0x2, 'A','E', 0x1, 0x0, }; unsigned char salt[8], key[34], verify[2], mac[10]; #endif char *filename; int crc=0,len,comp_size=data_size; uLongf destlen=data_size+data_size/500+12; char *compbuffer; compbuffer = malloc(destlen); if (!compbuffer) { fprintf(stderr, "No more memory.\n"); exit (1); } #ifdef HAVE_LIBCRYPTO if (zip_info->passwd) { RAND_bytes(salt, sizeof(salt)); PKCS5_PBKDF2_HMAC_SHA1(zip_info->passwd, strlen(zip_info->passwd), salt, sizeof(salt), 1000, sizeof(key), key); verify[0]=key[32]; verify[1]=key[33]; } else { #endif crc=crc32(0, NULL, 0); crc=crc32(crc, (unsigned char *)data, data_size); #ifdef HAVE_LIBCRYPTO } #endif lfh.zipmthd=zip_info->compression_level ? 8:0; #ifdef HAVE_ZLIB if (zip_info->compression_level) { int error=compress2_int((Byte *)compbuffer, &destlen, (Bytef *)data, data_size, zip_info->compression_level); if (error == Z_OK) { if (destlen < data_size) { data=compbuffer; comp_size=destlen; } else lfh.zipmthd=0; } else { fprintf(stderr,"compress2 returned %d\n", error); } } #endif lfh.zipcrc=crc; lfh.zipsize=comp_size; lfh.zipuncmp=data_size; #ifdef HAVE_LIBCRYPTO if (zip_info->passwd) { enc.compress_method=lfh.zipmthd; lfh.zipmthd=99; lfh.zipxtraln+=sizeof(enc); lfh.zipgenfld|=1; lfh.zipsize+=sizeof(salt)+sizeof(verify)+sizeof(mac); } #endif cd.zipccrc=crc; cd.zipcsiz=lfh.zipsize; cd.zipcunc=data_size; cd.zipcmthd=lfh.zipmthd; if (zip_info->zip64) { cd.zipofst=0xffffffff; cd.zipcxtl+=sizeof(cd_ext); } #ifdef HAVE_LIBCRYPTO if (zip_info->passwd) { cd.zipcmthd=99; cd.zipcxtl+=sizeof(enc); cd.zipcflg|=1; } #endif filename=g_alloca(filelen+1); strcpy(filename, name); len=strlen(filename); while (len < filelen) { filename[len++]='_'; } filename[filelen]='\0'; zip_write(zip_info, &lfh, sizeof(lfh)); zip_write(zip_info, filename, filelen); zip_info->offset+=sizeof(lfh)+filelen; #ifdef HAVE_LIBCRYPTO if (zip_info->passwd) { unsigned char counter[16], xor[16], *datap=(unsigned char *)data; int size=comp_size; AES_KEY aeskey; zip_write(zip_info, &enc, sizeof(enc)); zip_write(zip_info, salt, sizeof(salt)); zip_write(zip_info, verify, sizeof(verify)); zip_info->offset+=sizeof(enc)+sizeof(salt)+sizeof(verify); AES_set_encrypt_key(key, 128, &aeskey); memset(counter, 0, sizeof(counter)); while (size > 0) { int i,curr_size,idx=0; do { counter[idx]++; } while (!counter[idx++]); AES_encrypt(counter, xor, &aeskey); curr_size=size; if (curr_size > sizeof(xor)) curr_size=sizeof(xor); for (i = 0 ; i < curr_size ; i++) *datap++^=xor[i]; size-=curr_size; } } #endif zip_write(zip_info, data, comp_size); zip_info->offset+=comp_size; #ifdef HAVE_LIBCRYPTO if (zip_info->passwd) { unsigned int maclen=sizeof(mac); unsigned char mactmp[maclen*2]; HMAC(EVP_sha1(), key+16, 16, (unsigned char *)data, comp_size, mactmp, &maclen); zip_write(zip_info, mactmp, sizeof(mac)); zip_info->offset+=sizeof(mac); } #endif fwrite(&cd, sizeof(cd), 1, zip_info->dir); fwrite(filename, filelen, 1, zip_info->dir); zip_info->dir_size+=sizeof(cd)+filelen; if (zip_info->zip64) { fwrite(&cd_ext, sizeof(cd_ext), 1, zip_info->dir); zip_info->dir_size+=sizeof(cd_ext); } #ifdef HAVE_LIBCRYPTO if (zip_info->passwd) { fwrite(&enc, sizeof(enc), 1, zip_info->dir); zip_info->dir_size+=sizeof(enc); } #endif free(compbuffer); }
int generateKey(const char *pass, const char *salt, char *out){ return PKCS5_PBKDF2_HMAC_SHA1(pass, -1, (unsigned char *) salt, strlen(SALT) + 1, NUM_ITERS, KEY_SIZE_BYTES, (unsigned char *) out); }
static int sc_pkcs15_derive_key(sc_context_t *ctx, const struct sc_algorithm_id *der_alg, const struct sc_algorithm_id *enc_alg, const char *passphrase, EVP_CIPHER_CTX *crypt_ctx, int enc_dec) { struct sc_pbkdf2_params *info; unsigned int key_len; const EVP_CIPHER *cipher; u8 *iv = NULL, key[64]; int r; if (!ctx || ! der_alg || !enc_alg) return SC_ERROR_NOT_SUPPORTED; /* XXX: We might also encounter PBES2 here */ if (der_alg->algorithm != SC_ALGORITHM_PBKDF2) { sc_error(ctx, "Unsupported key derivation algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; } switch (enc_alg->algorithm) { case SC_ALGORITHM_3DES: cipher = EVP_des_ede3_cbc(); iv = (u8 *) enc_alg->params; break; case SC_ALGORITHM_DES: cipher = EVP_des_cbc(); iv = (u8 *) enc_alg->params; break; default: sc_error(ctx, "Unsupported key encryption algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; } if (!iv) { sc_error(ctx, "Unsupported key encryption parameters.\n"); return SC_ERROR_NOT_SUPPORTED; } key_len = EVP_CIPHER_key_length(cipher); info = (struct sc_pbkdf2_params *) der_alg->params; if (!info) { sc_error(ctx, "Key parameters missing.\n"); return SC_ERROR_INVALID_ARGUMENTS; } if (info->key_length && info->key_length != key_len) { sc_error(ctx, "Incompatible key length.\n"); return SC_ERROR_INVALID_ARGUMENTS; } if (key_len > sizeof(key)) { sc_error(ctx, "Huge key length (%u).\n", key_len); return SC_ERROR_INVALID_ARGUMENTS; } r = PKCS5_PBKDF2_HMAC_SHA1(passphrase, -1, info->salt, info->salt_len, info->iterations, key_len, key); if (r == 0) { sc_error(ctx, "Key derivation failed.\n"); return SC_ERROR_INTERNAL; /* for lack of something better */ } /* Now we have the key. Set up the cipher context */ memset(crypt_ctx, 0, sizeof(*crypt_ctx)); EVP_CipherInit(crypt_ctx, cipher, key, iv, enc_dec); return 0; }