123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK.
- All rights reserved.
- LICENSE TERMS
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
- DISCLAIMER
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 24/01/2003
- This file implements password based file encryption and authentication
- using AES in CTR mode, HMAC-SHA1 authentication and RFC2898 password
- based key derivation.
- */
- #include <memory.h>
- #include "fileenc.h"
- #if defined(__cplusplus)
- extern "C"
- {
- #endif
- /* subroutine for data encryption/decryption */
- /* this could be speeded up a lot by aligning */
- /* buffers and using 32 bit operations */
- static void encr_data(unsigned char data[], unsigned long d_len, fcrypt_ctx cx[1])
- {
- unsigned long i = 0, pos = cx->encr_pos;
- while (i < d_len) {
- if (pos == AES_BLOCK_SIZE) {
- unsigned int j = 0;
- /* increment encryption nonce */
- while (j < 8 && !++cx->nonce[j])
- ++j;
- /* encrypt the nonce to form next xor buffer */
- aes_encrypt(cx->nonce, cx->encr_bfr, cx->encr_ctx);
- pos = 0;
- }
- data[i++] ^= cx->encr_bfr[pos++];
- }
- cx->encr_pos = (unsigned int)pos;
- }
- int fcrypt_init(
- int mode, /* the mode to be used (input) */
- const unsigned char pwd[], /* the user specified password (input) */
- unsigned int pwd_len, /* the length of the password (input) */
- const unsigned char salt[], /* the salt (input) */
- #ifdef PASSWORD_VERIFIER
- unsigned char pwd_ver[PWD_VER_LENGTH], /* 2 byte password verifier (output) */
- #endif
- fcrypt_ctx cx[1]) /* the file encryption context (output) */
- {
- unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH];
- if (pwd_len > MAX_PWD_LENGTH)
- return PASSWORD_TOO_LONG;
- if (mode < 1 || mode > 3)
- return BAD_MODE;
- cx->mode = mode;
- cx->pwd_len = pwd_len;
- /* derive the encryption and authentication keys and the password verifier */
- derive_key(pwd, pwd_len, salt, SALT_LENGTH(mode), KEYING_ITERATIONS,
- kbuf, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH);
- /* initialise the encryption nonce and buffer pos */
- cx->encr_pos = AES_BLOCK_SIZE;
- /* if we need a random component in the encryption */
- /* nonce, this is where it would have to be set */
- memset(cx->nonce, 0, AES_BLOCK_SIZE * sizeof(unsigned char));
- /* initialise for encryption using key 1 */
- aes_encrypt_key(kbuf, KEY_LENGTH(mode), cx->encr_ctx);
- /* initialise for authentication using key 2 */
- hmac_sha_begin(cx->auth_ctx);
- hmac_sha_key(kbuf + KEY_LENGTH(mode), KEY_LENGTH(mode), cx->auth_ctx);
- #ifdef PASSWORD_VERIFIER
- memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH);
- #endif
- return GOOD_RETURN;
- }
- /* perform 'in place' encryption and authentication */
- void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])
- {
- encr_data(data, data_len, cx);
- hmac_sha_data(data, data_len, cx->auth_ctx);
- }
- /* perform 'in place' authentication and decryption */
- void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])
- {
- hmac_sha_data(data, data_len, cx->auth_ctx);
- encr_data(data, data_len, cx);
- }
- /* close encryption/decryption and return the MAC value */
- int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1])
- {
- hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);
- return MAC_LENGTH(cx->mode); /* return MAC length in bytes */
- }
- #if defined(__cplusplus)
- }
- #endif
|