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