crypto_obfuscate.c revision 9faab6d48145d3a0d7b9a225ed35bdcaa32eca2c
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek/*
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek SSSD
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek Password obfuscation logic
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek Authors:
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek George McCollister <george.mccollister@gmail.com>
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek Copyright (C) George McCollister 2012
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek This program is free software; you can redistribute it and/or modify
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek it under the terms of the GNU General Public License as published by
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 3 of the License, or
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek (at your option) any later version.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek This program is distributed in the hope that it will be useful,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek but WITHOUT ANY WARRANTY; without even the implied warranty of
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek GNU General Public License for more details.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU General Public License
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek along with this program. If not, see <http://www.gnu.org/licenses/>.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek*/
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek/*
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * READ ME:
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * Please note that password obfuscation does not improve security in any
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * way. It is just a mechanism to make the password human-unreadable. If you
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * need to secure passwords in your application, you should probably take a
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * look at storing passwords in NSS-backed database.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include "config.h"
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include <talloc.h>
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include <errno.h>
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include "util/util.h"
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include "util/crypto/sss_crypto.h"
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include <openssl/evp.h>
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include <openssl/rand.h>
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#define OBF_BUFFER_SENTINEL "\0\1\2\3"
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#define OBF_BUFFER_SENTINEL_SIZE 4
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekstruct crypto_mech_data {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek const EVP_CIPHER * (*cipher)(void);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek uint16_t keylen;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek uint16_t bsize;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek};
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekstatic struct crypto_mech_data cmdata[] = {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek /* AES with automatic padding, 256b key, 128b block */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek { EVP_aes_256_cbc, 32, 16 },
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek /* sentinel */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek { 0, 0, 0 }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek};
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekstatic struct crypto_mech_data *get_crypto_mech_data(enum obfmethod meth)
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek{
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (meth >= NUM_OBFMETHODS) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported cipher type\n");
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return NULL;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return &cmdata[meth];
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek}
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekint sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek enum obfmethod meth, char **obfpwd)
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek{
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int ret;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek EVP_CIPHER_CTX ctx;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek struct crypto_mech_data *mech_props;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek TALLOC_CTX *tmp_ctx = NULL;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek unsigned char *keybuf;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek unsigned char *ivbuf;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek unsigned char *cryptotext;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int ct_maxsize;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int ctlen = 0;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int digestlen = 0;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int result_len;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek unsigned char *obfbuf;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek size_t obufsize = 0;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek size_t p = 0;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek tmp_ctx = talloc_new(NULL);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (!tmp_ctx) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return ENOMEM;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek EVP_CIPHER_CTX_init(&ctx);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek mech_props = get_crypto_mech_data(meth);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (mech_props == NULL) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = EINVAL;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek keybuf = talloc_array(tmp_ctx, unsigned char, mech_props->keylen);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (keybuf == NULL) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = ENOMEM;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ivbuf = talloc_array(tmp_ctx, unsigned char, mech_props->bsize);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (ivbuf == NULL) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = ENOMEM;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
66f756d437658cc464bfb5647c97efd0cf77f933Jan Engelhardt RAND_bytes(keybuf, mech_props->keylen);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek RAND_bytes(ivbuf, mech_props->bsize);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek /* cryptotext buffer must be at least len(plaintext)+blocksize */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ct_maxsize = plen + (mech_props->bsize);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek cryptotext = talloc_array(tmp_ctx, unsigned char, ct_maxsize);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (!cryptotext) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = ENOMEM;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (!EVP_EncryptInit_ex(&ctx, mech_props->cipher(), 0, keybuf, ivbuf)) {
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek DEBUG(SSSDBG_CRIT_FAILURE, "Failure to initialize cipher contex\n");
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek ret = EIO;
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek goto done;
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek }
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek /* sample data we'll encrypt and decrypt */
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek if (!EVP_EncryptUpdate(&ctx, cryptotext, &ctlen, (const unsigned char*)password, plen)) {
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek DEBUG(SSSDBG_CRIT_FAILURE, "Cannot execute the encryption operation\n");
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek ret = EIO;
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek goto done;
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek }
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering if(!EVP_EncryptFinal_ex(&ctx, cryptotext+ctlen, &digestlen)) {
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering DEBUG(SSSDBG_CRIT_FAILURE, "Cannot finialize the encryption operation\n");
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering ret = EIO;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering goto done;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering }
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering result_len = ctlen + digestlen;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering if (result_len < 0 || result_len > UINT16_MAX) {
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering ret = ERANGE;
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering goto done;
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering }
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering /* Pack the obfuscation buffer */
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering /* The buffer consists of:
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering * uint16_t the type of the cipher
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering * uint16_t length of the cryptotext in bytes (clen)
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering * uint8_t[klen] key
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering * uint8_t[blen] IV
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering * uint8_t[clen] cryptotext
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering * 4 bytes of "sentinel" denoting end of the buffer
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering */
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering obufsize = sizeof(uint16_t) + sizeof(uint16_t) +
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering mech_props->keylen + mech_props->bsize +
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering result_len + OBF_BUFFER_SENTINEL_SIZE;
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering obfbuf = talloc_array(tmp_ctx, unsigned char, obufsize);
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering if (!obfbuf) {
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering ret = ENOMEM;
88ae7333ee052e64607ae6678fe0e84991fe3482Zbigniew Jędrzejewski-Szmek goto done;
88ae7333ee052e64607ae6678fe0e84991fe3482Zbigniew Jędrzejewski-Szmek }
4f50d2efbac87aba0505b9f998bf3e4bde64c214Zbigniew Jędrzejewski-Szmek
4f50d2efbac87aba0505b9f998bf3e4bde64c214Zbigniew Jędrzejewski-Szmek DEBUG(SSSDBG_TRACE_FUNC, "Writing method: %d\n", meth);
88ae7333ee052e64607ae6678fe0e84991fe3482Zbigniew Jędrzejewski-Szmek SAFEALIGN_SET_UINT16(&obfbuf[p], meth, &p);
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek DEBUG(SSSDBG_TRACE_FUNC, "Writing bufsize: %d\n", result_len);
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek SAFEALIGN_SET_UINT16(&obfbuf[p], result_len, &p);
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek safealign_memcpy(&obfbuf[p], keybuf, mech_props->keylen, &p);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek safealign_memcpy(&obfbuf[p], ivbuf, mech_props->bsize, &p);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek safealign_memcpy(&obfbuf[p], cryptotext, result_len, &p);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek safealign_memcpy(&obfbuf[p], OBF_BUFFER_SENTINEL,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek OBF_BUFFER_SENTINEL_SIZE, &p);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek /* Base64 encode the resulting buffer */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *obfpwd = sss_base64_encode(mem_ctx, obfbuf, obufsize);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (*obfpwd == NULL) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = ENOMEM;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering ret = EOK;
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering
d9130355ee0530117518ff24354bdd552d030238Lennart Poetteringdone:
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering talloc_free(tmp_ctx);
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering EVP_CIPHER_CTX_cleanup(&ctx);
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering return ret;
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering}
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering
d9130355ee0530117518ff24354bdd552d030238Lennart Poetteringint sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering char **password)
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering{
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering int ret;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek EVP_CIPHER_CTX ctx;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek TALLOC_CTX *tmp_ctx = NULL;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek struct crypto_mech_data *mech_props;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int plainlen;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int digestlen;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek unsigned char *obfbuf = NULL;
f5ca75f4a1f9f97a23c8bb70ee89cf669f9bb425Thomas Hindoe Paaboel Andersen size_t obflen;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek char *pwdbuf;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek /* for unmarshaling data */
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering uint16_t meth;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering uint16_t ctsize;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering size_t p = 0;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering unsigned char *cryptotext;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering unsigned char *keybuf;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering unsigned char *ivbuf;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering unsigned char sentinel_check[OBF_BUFFER_SENTINEL_SIZE];
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering tmp_ctx = talloc_new(NULL);
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering if (!tmp_ctx) {
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering return ENOMEM;
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering }
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek EVP_CIPHER_CTX_init(&ctx);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek /* Base64 decode the incoming buffer */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek obfbuf = sss_base64_decode(tmp_ctx, b64encoded, &obflen);
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering if (!obfbuf) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = ENOMEM;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering /* unpack obfuscation buffer */
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering SAFEALIGN_COPY_UINT16_CHECK(&meth, obfbuf+p, obflen, &p);
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering DEBUG(SSSDBG_TRACE_FUNC, "Read method: %d\n", meth);
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering SAFEALIGN_COPY_UINT16_CHECK(&ctsize, obfbuf+p, obflen, &p);
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering DEBUG(SSSDBG_TRACE_FUNC, "Read bufsize: %d\n", ctsize);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek mech_props = get_crypto_mech_data(meth);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (mech_props == NULL) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = EINVAL;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek /* check that we got sane mechanism properties and cryptotext size */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek memcpy(sentinel_check,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek obfbuf + p + mech_props->keylen + mech_props->bsize + ctsize,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek OBF_BUFFER_SENTINEL_SIZE);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (memcmp(sentinel_check, OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE) != 0) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek DEBUG(SSSDBG_CRIT_FAILURE, "Obfuscation buffer seems corrupt, aborting\n");
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = EFAULT;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering /* copy out key, ivbuf and cryptotext */
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering keybuf = talloc_array(tmp_ctx, unsigned char, mech_props->keylen);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (keybuf == NULL) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek ret = ENOMEM;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek goto done;
}
safealign_memcpy(keybuf, obfbuf+p, mech_props->keylen, &p);
ivbuf = talloc_array(tmp_ctx, unsigned char, mech_props->bsize);
if (ivbuf == NULL) {
ret = ENOMEM;
goto done;
}
safealign_memcpy(ivbuf, obfbuf+p, mech_props->bsize, &p);
cryptotext = talloc_array(tmp_ctx, unsigned char, ctsize);
if (cryptotext == NULL) {
ret = ENOMEM;
goto done;
}
safealign_memcpy(cryptotext, obfbuf+p, ctsize, &p);
pwdbuf = talloc_array(tmp_ctx, char, ctsize);
if (!pwdbuf) {
ret = ENOMEM;
goto done;
}
if (!EVP_DecryptInit_ex(&ctx, mech_props->cipher(), 0, keybuf, ivbuf)) {
ret = EIO;
goto done;
}
/* sample data we'll encrypt and decrypt */
if (!EVP_DecryptUpdate(&ctx, (unsigned char*)pwdbuf, &plainlen, cryptotext, ctsize)) {
ret = EIO;
goto done;
}
if(!EVP_DecryptFinal_ex(&ctx, (unsigned char*)pwdbuf+plainlen, &digestlen)) {
ret = EIO;
goto done;
}
*password = talloc_move(mem_ctx, &pwdbuf);
ret = EOK;
done:
talloc_free(tmp_ctx);
EVP_CIPHER_CTX_cleanup(&ctx);
return ret;
}