1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 /* 21 * XSEC 22 * 23 * XSECCryptoSymmetricKey := Bulk encryption algorithms should all be 24 * implemented via this interface 25 * 26 * Author(s): Berin Lautenbach 27 * 28 * $Id: OpenSSLCryptoSymmetricKey.hpp 1808174 2017-09-12 21:50:30Z scantor $ 29 * 30 */ 31 32 33 34 #ifndef OPENSSLCRYPTOSYMMETRICKEY_INCLUDE 35 #define OPENSSLCRYPTOSYMMETRICKEY_INCLUDE 36 37 #include <xsec/framework/XSECDefs.hpp> 38 #include <xsec/enc/XSECCryptoSymmetricKey.hpp> 39 40 #if defined (XSEC_HAVE_OPENSSL) 41 42 // OpenSSL Includes 43 44 #include <openssl/evp.h> 45 46 #define MAX_BLOCK_SIZE 32 47 48 /** 49 * \ingroup opensslcrypto 50 */ 51 52 /** 53 * \brief Base interface definition for symmetric key material. 54 * 55 * This is the implementation for a wrapper of OpenSSL symmetric 56 * crypto functions. 57 */ 58 59 class XSEC_EXPORT OpenSSLCryptoSymmetricKey : public XSECCryptoSymmetricKey { 60 61 public : 62 63 /** @name Constructors and Destructors */ 64 //@{ 65 66 /** 67 * \brief Constructor 68 * 69 * Can only construct a Symmetric key if we know what type it is 70 **/ 71 72 OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::SymmetricKeyType type); 73 74 /** 75 * \brief Destructor 76 * 77 * Implementations must ensure that the held key is properly destroyed 78 * (overwritten) when key objects are deleted. 79 */ 80 81 virtual ~OpenSSLCryptoSymmetricKey(); 82 83 //@} 84 85 /** @name Basic CryptoKey Interface methods */ 86 //@{ 87 88 /** 89 * \brief Returns a string that identifies the crypto owner of this library. 90 */ 91 92 virtual const XMLCh * getProviderName() const; 93 94 /** 95 * \brief Clone the key 96 * 97 * All keys need to be able to copy themselves and return 98 * a pointer to the copy. This allows the library to 99 * duplicate keys. 100 */ 101 102 virtual XSECCryptoKey * clone() const; 103 104 //@} 105 106 /** @name Symmetric key interface methods */ 107 //@{ 108 109 /** 110 * \brief What type of symmetric key is this? 111 * 112 * There are a number of different types of symmetric key. 113 * This method allows callers to determine the type of this 114 * particular key 115 */ 116 117 SymmetricKeyType getSymmetricKeyType(void) const; 118 119 /** 120 * \brief Set the key from the provided bytes 121 * 122 * Symmetric keys can all be loaded from a buffer containing a series 123 * of bytes. 124 * 125 * @param key The buffer containing the key bytes 126 * @param keyLen The number of key bytes in the buffer 127 * 128 */ 129 130 void setKey(const unsigned char * key, unsigned int keyLen); 131 132 /** 133 * \brief Initialise an decryption process 134 * 135 * Setup the key to get ready for a decryption session. 136 * Callers can pass in an IV. If one is not provided, 137 * but the algorithm requires one (e.g. 3DES_CBC), then 138 * implementations should assume that the start of the 139 * cipher text stream will in fact be the IV. 140 * 141 * @param doPad By default, we perform padding for last block 142 * @param mode mode selection (Currently ECB or CBC mode only) 143 * @param iv Initialisation Vector to be used. NULL if one is 144 * not required, or if IV will be set from data stream 145 * @param tag Authentication tag to be used for AEAD ciphers 146 * @param taglen length of Authentication Tag 147 * @returns true if the initialisation succeeded. 148 */ 149 150 virtual bool decryptInit(bool doPad = true, 151 SymmetricKeyMode mode = MODE_CBC, 152 const unsigned char * iv = NULL, 153 const unsigned char* tag = NULL, 154 unsigned int taglen = 0); 155 156 /** 157 * \brief Continue an decrypt operation using this key. 158 * 159 * Decryption must have been set up using an encryptInit 160 * call. Takes the inBuf and continues a decryption operation, 161 * writing the output to outBuf. 162 * 163 * This function does not have to guarantee that all input 164 * will be decrypted. In cases where the input is not a length 165 * of the block size, the implementation will need to hold back 166 * cipher-text to be handles during the next operation. 167 * 168 * @note While maxOutLength is defined, the OpenSSL libraries will 169 * not read the value, so the onus is on the caller to ensure the 170 * buffer is long enough to hold the output! 171 * 172 * @param inBuf Octets to be decrypted 173 * @param plainBuf Buffer to place output in 174 * @param inLength Number of bytes to decrypt 175 * @param maxOutLength Maximum number of bytes to place in output 176 * buffer 177 * @returns Bytes placed in output Buffer 178 */ 179 180 virtual unsigned int decrypt(const unsigned char * inBuf, 181 unsigned char * plainBuf, 182 unsigned int inLength, 183 unsigned int maxOutLength); 184 185 /** 186 * \brief Finish a decryption operation 187 * 188 * Complete a decryption process. No cipher text is passed in, 189 * as this should simply be removing any remaining text from 190 * the plain storage buffer. 191 * 192 * May throw an exception if there is some stored cipher text 193 * that is not the length of the block size for block algorithms. 194 * 195 * @note While maxOutLength is defined, the OpenSSL libraries will 196 * not read the value, so the onus is on the caller to ensure the 197 * buffer is long enough to hold the output! 198 * 199 * @param plainBuf Buffer to place any remaining plain text in 200 * @param maxOutLength Maximum number of bytes to pace in output 201 * @returns Bytes placed in output buffer 202 */ 203 204 virtual unsigned int decryptFinish(unsigned char * plainBuf, 205 unsigned int maxOutLength); 206 207 /** 208 * \brief Initialise an encryption process 209 * 210 * Setup the key to get ready for a decryption session. 211 * Callers can pass in an IV. If one is not provided, 212 * but the algorithm requires one (e.g. 3DES_CBC), then 213 * implementations are required to generate one. 214 * 215 * @param doPad By default, we perform padding for last block 216 * @param mode What mode to handle blocks (Currently CBC or ECB) 217 * @param iv Initialisation Vector to be used. NULL if one is 218 * not required, or if IV is to be generated 219 * @returns true if the initialisation succeeded. 220 */ 221 222 virtual bool encryptInit(bool doPad = true, 223 SymmetricKeyMode mode = MODE_CBC, 224 const unsigned char * iv = NULL); 225 226 /** 227 * \brief Continue an encryption operation using this key. 228 * 229 * Encryption must have been set up using an encryptInit 230 * call. Takes the inBuf and continues a encryption operation, 231 * writing the output to outBuf. 232 * 233 * This function does not have to guarantee that all input 234 * will be encrypted. In cases where the input is not a length 235 * of the block size, the implementation will need to hold back 236 * plain-text to be handled during the next operation. 237 * 238 * @param inBuf Octets to be encrypted 239 * @param cipherBuf Buffer to place output in 240 * @param inLength Number of bytes to encrypt 241 * @param maxOutLength Maximum number of bytes to place in output 242 * buffer 243 * @returns Bytes placed in output Buffer 244 */ 245 246 virtual unsigned int encrypt(const unsigned char * inBuf, 247 unsigned char * cipherBuf, 248 unsigned int inLength, 249 unsigned int maxOutLength); 250 251 /** 252 * \brief Finish a encryption operation 253 * 254 * Complete a encryption process. No plain text is passed in, 255 * as this should simply be removing any remaining text from 256 * the plain storage buffer and creating a final padded block. 257 * 258 * Padding is performed by taking the remaining block, and 259 * setting the last byte to equal the number of bytes of 260 * padding. If the plain was an exact multiple of the block size, 261 * then an extra block of padding will be used. For example, if 262 * the block size is 8 bytes, and there were three remaining plain 263 * text bytes (0x01, 0x02 and 0x03), the final block will be : 264 * 265 * 0x010203????????05 266 * 267 * @param plainBuf Buffer to place final block of cipher text in 268 * @param maxOutLength Maximum number of bytes to pace in output 269 * @param taglen length of Authentication Tag 270 * @returns Bytes placed in output buffer 271 */ 272 273 virtual unsigned int encryptFinish(unsigned char * plainBuf, 274 unsigned int maxOutLength, 275 unsigned int taglen = 0); 276 277 //@} 278 279 /** @name OpenSSL Library Specific functions */ 280 //@{ 281 282 /** 283 * \brief Get OpenSSL cipher context structure 284 */ 285 getOpenSSLEVP_CIPHER_CTX(void)286 EVP_CIPHER_CTX * getOpenSSLEVP_CIPHER_CTX(void) {return mp_ctx;} 287 288 /** 289 * \brief Get OpenSSL cipher context structure 290 */ 291 getOpenSSLEVP_CIPHER_CTX(void) const292 const EVP_CIPHER_CTX * getOpenSSLEVP_CIPHER_CTX(void) const {return mp_ctx;} 293 294 //@} 295 296 private: 297 298 // Unimplemented constructors 299 300 OpenSSLCryptoSymmetricKey(); 301 OpenSSLCryptoSymmetricKey(const OpenSSLCryptoSymmetricKey &); 302 OpenSSLCryptoSymmetricKey & operator= (const OpenSSLCryptoSymmetricKey &); 303 304 // Private functions 305 int decryptCtxInit(const unsigned char* iv, const unsigned char* tag, unsigned int taglen); 306 307 // Private variables 308 SymmetricKeyType m_keyType; 309 SymmetricKeyMode m_keyMode; 310 EVP_CIPHER_CTX *mp_ctx; // OpenSSL Cipher Context structure 311 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) 312 EVP_CIPHER_CTX m_ctx_space; // OpenSSL Cipher Context structure - store 313 #endif 314 safeBuffer m_keyBuf; // Holder of the key 315 safeBuffer m_tagBuf; // Holder of authentication tag 316 unsigned int m_keyLen; 317 bool m_initialised; // Is the context ready to work? 318 unsigned char m_lastBlock[MAX_BLOCK_SIZE]; 319 int m_blockSize; 320 int m_ivSize; 321 int m_bytesInLastBlock; 322 bool m_ivSent; // Has the IV been put in the stream 323 bool m_doPad; // Do we pad last block? 324 }; 325 326 #endif /* XSEC_HAVE_OPENSSL */ 327 #endif /* OPENSSLCRYPTOSYMMETRICKEY_INCLUDE */ 328