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: WinCAPICryptoSymmetricKey.hpp 1808174 2017-09-12 21:50:30Z scantor $ 29 * 30 */ 31 32 33 34 #ifndef WINCAPICRYPTOSYMMETRICKEY_INCLUDE 35 #define WINCAPICRYPTOSYMMETRICKEY_INCLUDE 36 37 #include <xsec/framework/XSECDefs.hpp> 38 #include <xsec/enc/XSECCryptoSymmetricKey.hpp> 39 40 #if defined (XSEC_HAVE_WINCAPI) 41 42 #if !defined(_WIN32_WINNT) 43 # define _WIN32_WINNT 0x0400 44 #endif 45 46 #include <wincrypt.h> 47 48 #define WINCAPI_MAX_BLOCK_SIZE 32 49 50 /** 51 * \ingroup wincapicrypto 52 */ 53 54 /** 55 * \brief Base interface definition for symmetric key material. 56 * 57 * This is the implementation for a wrapper of Windows CryptoAPI symmetric 58 * crypto functions. 59 */ 60 61 class XSEC_EXPORT WinCAPICryptoSymmetricKey : public XSECCryptoSymmetricKey { 62 63 public : 64 65 /** @name Constructors and Destructors */ 66 //@{ 67 68 /** 69 * \brief Constructor 70 * 71 * Can only construct a Symmetric key if we know what type it is 72 * 73 * @param prov The appropriate provider that supports the required algorithm. 74 * Can be 0 if the app is going to pass in an octet via setKey, as the library 75 * will use its own internal key store and handle to CSP. 76 * @param type The type of key (i.e. algorithm) to create 77 **/ 78 79 WinCAPICryptoSymmetricKey(HCRYPTPROV prov, XSECCryptoSymmetricKey::SymmetricKeyType type); 80 81 /** 82 * \brief Destructor 83 * 84 * Implementations must ensure that the held key is properly destroyed 85 * (overwritten) when key objects are deleted. 86 */ 87 88 virtual ~WinCAPICryptoSymmetricKey(); 89 90 //@} 91 92 /** @name Basic CryptoKey Interface methods */ 93 //@{ 94 95 /** 96 * \brief Returns a string that identifies the crypto owner of this library. 97 */ 98 getProviderName() const99 virtual const XMLCh * getProviderName() const {return DSIGConstants::s_unicodeStrPROVWinCAPI;} 100 101 /** 102 * \brief Clone the key 103 * 104 * All keys need to be able to copy themselves and return 105 * a pointer to the copy. This allows the library to 106 * duplicate keys. 107 */ 108 109 virtual XSECCryptoKey * clone() const; 110 111 //@} 112 113 /** @name Symmetric key interface methods */ 114 //@{ 115 116 /** 117 * \brief What type of symmetric key is this? 118 * 119 * There are a number of different types of symmetric key. 120 * This method allows callers to determine the type of this 121 * particular key 122 */ 123 getSymmetricKeyType(void) const124 SymmetricKeyType getSymmetricKeyType(void) const {return m_keyType;} 125 126 /** 127 * \brief Set the key from the provided bytes 128 * 129 * Symmetric keys can all be loaded from a buffer containing a series 130 * of bytes. 131 * 132 * @param key The buffer containing the key bytes 133 * @param keyLen The number of key bytes in the buffer 134 * 135 */ 136 137 void setKey(const unsigned char * key, unsigned int keyLen); 138 139 /** 140 * \brief Initialise an decryption process 141 * 142 * Setup the key to get ready for a decryption session. 143 * Callers can pass in an IV. If one is not provided, 144 * but the algorithm requires one (e.g. 3DES_CBC), then 145 * implementations should assume that the start of the 146 * cipher text stream will in fact be the IV. 147 * 148 * @param doPad By default, we perform padding for last block 149 * @param mode mode selection (Currently ECB or CBC mode only) 150 * @param iv Initialisation Vector to be used. NULL if one is 151 * not required, or if IV will be set from data stream 152 * @param tag Authentication tag to be used for AEAD ciphers 153 * @param taglen length of Authentication Tag 154 * @returns true if the initialisation succeeded. 155 */ 156 157 virtual bool decryptInit(bool doPad = true, 158 SymmetricKeyMode mode = MODE_CBC, 159 const unsigned char * iv = NULL, 160 const unsigned char* tag = NULL, 161 unsigned int taglen = 0); 162 163 /** 164 * \brief Continue an decrypt operation using this key. 165 * 166 * Decryption must have been set up using an encryptInit 167 * call. Takes the inBuf and continues a decryption operation, 168 * writing the output to outBuf. 169 * 170 * This function does not have to guarantee that all input 171 * will be decrypted. In cases where the input is not a length 172 * of the block size, the implementation will need to hold back 173 * cipher-text to be handles during the next operation. 174 * 175 * @note While maxOutLength is defined, the WinCAPI library will 176 * not read the value, so the onus is on the caller to ensure the 177 * buffer is long enough to hold the output! 178 * 179 * @param inBuf Octets to be decrypted 180 * @param plainBuf Buffer to place output in 181 * @param inLength Number of bytes to decrypt 182 * @param maxOutLength Maximum number of bytes to place in output 183 * buffer 184 * @returns Bytes placed in output Buffer 185 */ 186 187 virtual unsigned int decrypt(const unsigned char * inBuf, 188 unsigned char * plainBuf, 189 unsigned int inLength, 190 unsigned int maxOutLength); 191 192 /** 193 * \brief Finish a decryption operation 194 * 195 * Complete a decryption process. No cipher text is passed in, 196 * as this should simply be removing any remaining text from 197 * the plain storage buffer. 198 * 199 * May throw an exception if there is some stored cipher text 200 * that is not the length of the block size for block algorithms. 201 * 202 * @note While maxOutLength is defined, the WinCAPI library will 203 * not read the value, so the onus is on the caller to ensure the 204 * buffer is long enough to hold the output! 205 * 206 * @param plainBuf Buffer to place any remaining plain text in 207 * @param maxOutLength Maximum number of bytes to pace in output 208 * @returns Bytes placed in output buffer 209 */ 210 211 virtual unsigned int decryptFinish(unsigned char * plainBuf, 212 unsigned int maxOutLength); 213 214 /** 215 * \brief Initialise an encryption process 216 * 217 * Setup the key to get ready for a decryption session. 218 * Callers can pass in an IV. If one is not provided, 219 * but the algorithm requires one (e.g. 3DES_CBC), then 220 * implementations are required to generate one. 221 * 222 * @param doPad By default, we perform padding for last block 223 * @param mode What mode to handle blocks (Currently CBC or ECB) 224 * @param iv Initialisation Vector to be used. NULL if one is 225 * not required, or if IV is to be generated 226 * @returns true if the initialisation succeeded. 227 */ 228 229 virtual bool encryptInit(bool doPad = true, 230 SymmetricKeyMode mode = MODE_CBC, 231 const unsigned char * iv = NULL); 232 233 /** 234 * \brief Continue an encryption operation using this key. 235 * 236 * Encryption must have been set up using an encryptInit 237 * call. Takes the inBuf and continues a encryption operation, 238 * writing the output to outBuf. 239 * 240 * This function does not have to guarantee that all input 241 * will be encrypted. In cases where the input is not a length 242 * of the block size, the implementation will need to hold back 243 * plain-text to be handled during the next operation. 244 * 245 * @param inBuf Octets to be encrypted 246 * @param cipherBuf Buffer to place output in 247 * @param inLength Number of bytes to encrypt 248 * @param maxOutLength Maximum number of bytes to place in output 249 * buffer 250 * @returns Bytes placed in output Buffer 251 */ 252 253 virtual unsigned int encrypt(const unsigned char * inBuf, 254 unsigned char * cipherBuf, 255 unsigned int inLength, 256 unsigned int maxOutLength); 257 258 /** 259 * \brief Finish a encryption operation 260 * 261 * Complete a encryption process. No plain text is passed in, 262 * as this should simply be removing any remaining text from 263 * the plain storage buffer and creating a final padded block. 264 * 265 * Padding is performed by taking the remaining block, and 266 * setting the last byte to equal the number of bytes of 267 * padding. If the plain was an exact multiple of the block size, 268 * then an extra block of padding will be used. For example, if 269 * the block size is 8 bytes, and there were three remaining plain 270 * text bytes (0x01, 0x02 and 0x03), the final block will be : 271 * 272 * 0x010203????????05 273 * 274 * @param plainBuf Buffer to place final block of cipher text in 275 * @param maxOutLength Maximum number of bytes to pace in output 276 * @param taglen length of Authentication Tag 277 * @returns Bytes placed in output buffer 278 */ 279 280 virtual unsigned int encryptFinish(unsigned char * plainBuf, 281 unsigned int maxOutLength, 282 unsigned int taglen = 0); 283 284 //@} 285 286 /** @name Windows utility functions */ 287 //@{ 288 289 /** 290 * \brief Create a symmetric key from a octet string 291 * 292 * Uses the ApacheKeyStore to wrap an octet string in a public key 293 * and then load it into the Apache Key Container within the defined 294 * CSP 295 * 296 * @param key The buffer of bytes to load from 297 * @param keyLen The number of bytes to load 298 * @param type The key type to create from the bytes 299 * @param prov If NULL, ignored. If non-null, but *prov == 0, the 300 * function will use an internal handle to a CSP and return the value 301 * in *prov. If *prov != 0, use contents of *prov as the provider to 302 * load the key into. NOTE - The provider <em>must</em> have a 303 * AT_KEYEXCHANGE key pair available. 304 * @returns a pointer to the key or 0 on failure 305 */ 306 307 static HCRYPTKEY createWindowsKey(const unsigned char * key, 308 unsigned int keyLen, 309 XSECCryptoSymmetricKey::SymmetricKeyType type, 310 HCRYPTPROV * prov); 311 312 313 314 private: 315 316 // Unimplemented constructors 317 318 WinCAPICryptoSymmetricKey(); 319 WinCAPICryptoSymmetricKey(const WinCAPICryptoSymmetricKey &); 320 WinCAPICryptoSymmetricKey & operator= (const WinCAPICryptoSymmetricKey &); 321 322 int decryptCtxInit(const unsigned char * iv); 323 void encryptCtxInit(const unsigned char * iv); 324 325 // Private variables 326 SymmetricKeyType m_keyType; 327 SymmetricKeyMode m_keyMode; // ECB or CBC 328 safeBuffer m_keyBuf; // Holder of the key 329 unsigned int m_keyLen; 330 bool m_initialised; 331 bool m_doPad; 332 333 unsigned char m_lastBlock[WINCAPI_MAX_BLOCK_SIZE]; 334 unsigned int m_bytesInLastBlock; 335 unsigned int m_blockSize; 336 unsigned int m_ivSize; 337 338 HCRYPTPROV m_p; 339 HCRYPTKEY m_k; 340 341 }; 342 343 #endif /* XSEC_HAVE_WINCAPI */ 344 #endif /* WINCAPICRYPTOSYMMETRICKEY_INCLUDE */ 345