91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina Simo Sorce <simo@redhat.com>
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina Copyright (C) Simo Sorce 2016
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina This program is free software; you can redistribute it and/or modify
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina it under the terms of the GNU General Public License as published by
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina the Free Software Foundation; either version 3 of the License, or
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina (at your option) any later version.
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina This program is distributed in the hope that it will be useful,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina GNU General Public License for more details.
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina You should have received a copy of the GNU General Public License
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březinaint sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (enctype != AES256CBC_HMAC_SHA256) return EINVAL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina cipher = mechs[AES256CBC_HMAC_SHA256].cipher();
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina digest = mechs[AES256CBC_HMAC_SHA256].digest();
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina if (!key || keylen != evpkeylen) return EINVAL;
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina hmackey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, keylen);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina /* We have no function to return the size of the output for arbitray HMAC
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * algorithms so we just truncate to the key size should the hmac be bigger
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina * (or pad with zeros should the HMAC be smaller) */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina outlen = plainlen + (2 * EVP_CIPHER_block_size(cipher))
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina /* First Encrypt */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = EVP_EncryptInit_ex(ctx, cipher, 0, key, evpivlen ? out : NULL);
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = EVP_EncryptUpdate(ctx, out + outlen, &tmplen, plaintext, plainlen);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = EVP_EncryptFinal_ex(ctx, out + outlen, &tmplen);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina /* Then HMAC */
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = EVP_DigestSignInit(mdctx, NULL, digest, NULL, hmackey);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = EVP_DigestSignUpdate(mdctx, out, outlen);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = EVP_DigestSignFinal(mdctx, &out[outlen], &slen);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březinaint sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (enctype != AES256CBC_HMAC_SHA256) return EINVAL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina cipher = mechs[AES256CBC_HMAC_SHA256].cipher();
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina digest = mechs[AES256CBC_HMAC_SHA256].digest();
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina if (!key || keylen != evpkeylen) return EINVAL;
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina hmackey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, keylen);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina /* We have no function to return the size of the output for arbitray HMAC
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina * algorithms so we just assume it was truncated to the key size should
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina * the hmac be bigger (or pad with zeros should the HMAC be smaller) */
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina /* First check HMAC */
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = EVP_DigestSignInit(mdctx, NULL, digest, NULL, hmackey);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = EVP_DigestSignUpdate(mdctx, ciphertext, cipherlen - hmaclen);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina ret = CRYPTO_memcmp(&ciphertext[cipherlen - hmaclen], out, hmaclen);
efa6c1f75c4c18bcc148d6e7efd429c2d56499adPavel Březina /* Then Decrypt */
91cf6f4c6069d6aff01aab171825e83a1a669e2fPavel Březina ret = EVP_DecryptInit_ex(ctx, cipher, 0, key, iv);