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