/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOCRYPT_CRYPTO_PRIVATE_H #define MONGOCRYPT_CRYPTO_PRIVATE_H #include "mongocrypt.h" #include "mongocrypt-buffer-private.h" #define MONGOCRYPT_KEY_LEN 96 #define MONGOCRYPT_IV_KEY_LEN 32 #define MONGOCRYPT_MAC_KEY_LEN 32 #define MONGOCRYPT_ENC_KEY_LEN 32 #define MONGOCRYPT_IV_LEN 16 #define MONGOCRYPT_HMAC_SHA512_LEN 64 #define MONGOCRYPT_HMAC_LEN 32 #define MONGOCRYPT_BLOCK_SIZE 16 #define MONGOCRYPT_HMAC_SHA256_LEN 32 #define MONGOCRYPT_TOKEN_KEY_LEN 32 typedef struct { int hooks_enabled; mongocrypt_crypto_fn aes_256_cbc_encrypt; mongocrypt_crypto_fn aes_256_cbc_decrypt; mongocrypt_crypto_fn aes_256_ctr_encrypt; mongocrypt_crypto_fn aes_256_ctr_decrypt; mongocrypt_crypto_fn aes_256_ecb_encrypt; mongocrypt_random_fn random; mongocrypt_hmac_fn hmac_sha_512; mongocrypt_hmac_fn hmac_sha_256; mongocrypt_hash_fn sha_256; void *ctx; } _mongocrypt_crypto_t; uint32_t _mongocrypt_calculate_ciphertext_len (uint32_t plaintext_len, mongocrypt_status_t *status); /* _mongocrypt_fle2aead_calculate_ciphertext_len returns the required length of * the ciphertext for _mongocrypt_fle2aead_do_encryption. */ uint32_t _mongocrypt_fle2aead_calculate_ciphertext_len (uint32_t plaintext_len, mongocrypt_status_t *status); /* _mongocrypt_fle2_calculate_ciphertext_len returns the required length of * the ciphertext for _mongocrypt_fle2_do_encryption. */ uint32_t _mongocrypt_fle2_calculate_ciphertext_len (uint32_t plaintext_len, mongocrypt_status_t *status); uint32_t _mongocrypt_calculate_plaintext_len (uint32_t ciphertext_len, mongocrypt_status_t *status); /* _mongocrypt_fle2aead_calculate_plaintext_len returns the required length of * the plaintext for _mongocrypt_fle2aead_do_decryption. */ uint32_t _mongocrypt_fle2aead_calculate_plaintext_len (uint32_t ciphertext_len, mongocrypt_status_t *status); /* _mongocrypt_fle2_calculate_plaintext_len returns the required length of * the plaintext for _mongocrypt_fle2_do_decryption. */ uint32_t _mongocrypt_fle2_calculate_plaintext_len (uint32_t ciphertext_len, mongocrypt_status_t *status); bool _mongocrypt_do_encryption (_mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *iv, const _mongocrypt_buffer_t *associated_data, const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *plaintext, _mongocrypt_buffer_t *ciphertext, uint32_t *bytes_written, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; bool _mongocrypt_do_decryption (_mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *associated_data, const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *ciphertext, _mongocrypt_buffer_t *plaintext, uint32_t *bytes_written, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; /* _mongocrypt_fle2aead_do_encryption does AEAD encryption. * It follows the construction described in the [AEAD with * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/) * * Note: The 96 byte key is split differently for FLE 2. * - FLE 1 uses first 32 bytes as the mac key, and the second 32 bytes as the * encryption key. * - FLE 2 uses first 32 bytes as encryption key, and the * second 32 bytes as the mac key. * Note: Attempting to encrypt a 0 length plaintext is an error. */ bool _mongocrypt_fle2aead_do_encryption (_mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *iv, const _mongocrypt_buffer_t *associated_data, const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *plaintext, _mongocrypt_buffer_t *ciphertext, uint32_t *bytes_written, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; bool _mongocrypt_fle2aead_do_decryption (_mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *associated_data, const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *ciphertext, _mongocrypt_buffer_t *plaintext, uint32_t *bytes_written, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; /* _mongocrypt_fle2_do_encryption does non-AEAD encryption. * @key is expected to be only an encryption key of size MONGOCRYPT_ENC_KEY_LEN. * Note: Attempting to encrypt a 0 length plaintext is an error. */ bool _mongocrypt_fle2_do_encryption (_mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *iv, const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *plaintext, _mongocrypt_buffer_t *ciphertext, uint32_t *bytes_written, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; /* _mongocrypt_fle2_do_decryption does non-AEAD decryption. * @key is expected to be only an encryption key of size MONGOCRYPT_ENC_KEY_LEN. */ bool _mongocrypt_fle2_do_decryption (_mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *ciphertext, _mongocrypt_buffer_t *plaintext, uint32_t *bytes_written, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; bool _mongocrypt_random (_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_t *out, uint32_t count, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; /* Generates a random number in the range [0, exclusive_upper_bound) in out. */ bool _mongocrypt_random_uint64 (_mongocrypt_crypto_t *crypto, uint64_t exclusive_upper_bound, uint64_t *out, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; /* Generates a random number in the range [0, exclusive_upper_bound) in out. */ bool _mongocrypt_random_int64 (_mongocrypt_crypto_t *crypto, int64_t exclusive_upper_bound, int64_t *out, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; /* Returns 0 if equal, non-zero otherwise */ int _mongocrypt_memequal (const void *const b1, const void *const b2, size_t len); /* * _mongocrypt_wrap_key encrypts a DEK with a KEK. * kek is an input Key Encryption Key. * dek is an input Data Encryption Key. * encrypted_dek the result of encrypting dek with kek. * encrypted_dek is always initialized. * Returns true if no error occurred. * Returns false and sets @status if an error occurred. */ bool _mongocrypt_wrap_key (_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_t *kek, _mongocrypt_buffer_t *dek, _mongocrypt_buffer_t *encrypted_dek, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; /* * _mongocrypt_unwrap_key decrypts an encrypted DEK with a KEK. * * kek is an input Key Encryption Key. * encrypted_dek is an input encrypted Data Encryption Key. * dek is the result of decrypting encrypted_dek with kek. * dek is always initialized. * Returns true if no error occurred. * Returns false and sets @status if an error occurred. */ bool _mongocrypt_unwrap_key (_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_t *kek, _mongocrypt_buffer_t *encrypted_dek, _mongocrypt_buffer_t *dek, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; bool _mongocrypt_calculate_deterministic_iv ( _mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *plaintext, const _mongocrypt_buffer_t *associated_data, _mongocrypt_buffer_t *out, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; /* * _mongocrypt_hmac_sha_256 computes the HMAC SHA-256. * * Uses the hmac_sha_256 hook set on @crypto if set, and otherwise * calls the native implementation. * * @out must have length 32 bytes. * * Returns true if no error occurred. * Returns false sets @status if an error occurred. */ bool _mongocrypt_hmac_sha_256 (_mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *in, _mongocrypt_buffer_t *out, mongocrypt_status_t *status); /* Crypto implementations must implement these functions. */ /* This variable must be defined in implementation files, and must be set to true when _crypto_init is successful. */ extern bool _native_crypto_initialized; void _native_crypto_init (void); typedef struct { const _mongocrypt_buffer_t *key; const _mongocrypt_buffer_t *iv; const _mongocrypt_buffer_t *in; _mongocrypt_buffer_t *out; uint32_t *bytes_written; mongocrypt_status_t *status; } aes_256_args_t; bool _native_crypto_aes_256_cbc_encrypt (aes_256_args_t args) MONGOCRYPT_WARN_UNUSED_RESULT; bool _native_crypto_aes_256_cbc_decrypt (aes_256_args_t args) MONGOCRYPT_WARN_UNUSED_RESULT; bool _native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *in, _mongocrypt_buffer_t *out, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; bool _native_crypto_random (_mongocrypt_buffer_t *out, uint32_t count, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; bool _native_crypto_aes_256_ctr_encrypt (aes_256_args_t args) MONGOCRYPT_WARN_UNUSED_RESULT; bool _native_crypto_aes_256_ctr_decrypt (aes_256_args_t args) MONGOCRYPT_WARN_UNUSED_RESULT; bool _native_crypto_hmac_sha_256 (const _mongocrypt_buffer_t *key, const _mongocrypt_buffer_t *in, _mongocrypt_buffer_t *out, mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; #endif /* MONGOCRYPT_CRYPTO_PRIVATE_H */