Produced by Araxis Merge on 9/25/2018 2:13:01 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
# | Location | File | Last Modified |
---|---|---|---|
1 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\crypto\provider | CipherCore.java | Mon Jan 22 14:46:50 2018 UTC |
2 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\crypto\provider | CipherCore.java | Wed Sep 12 16:22:16 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 2 | 2320 |
Changed | 1 | 2 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
Whitespace | |
---|---|
Character case | Differences in character case are significant |
Line endings | Differences in line endings (CR and LF characters) are ignored |
CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
1 | /* | |
2 | * Copyrig ht (c) 200 2, 2017, O racle and/ or its aff iliates. A ll rights reserved. | |
3 | * DO NOT ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER. | |
4 | * | |
5 | * This co de is free software; you can r edistribut e it and/o r modify i t | |
6 | * under t he terms o f the GNU General Pu blic Licen se version 2 only, a s | |
7 | * publish ed by the Free Softw are Founda tion. Ora cle design ates this | |
8 | * particu lar file a s subject to the "Cl asspath" e xception a s provided | |
9 | * by Orac le in the LICENSE fi le that ac companied this code. | |
10 | * | |
11 | * This co de is dist ributed in the hope that it wi ll be usef ul, but WI THOUT | |
12 | * ANY WAR RANTY; wit hout even the implie d warranty of MERCHA NTABILITY or | |
13 | * FITNESS FOR A PAR TICULAR PU RPOSE. Se e the GNU General Pu blic Licen se | |
14 | * version 2 for mor e details (a copy is included in the LIC ENSE file that | |
15 | * accompa nied this code). | |
16 | * | |
17 | * You sho uld have r eceived a copy of th e GNU Gene ral Public License v ersion | |
18 | * 2 along with this work; if not, write to the Fr ee Softwar e Foundati on, | |
19 | * Inc., 5 1 Franklin St, Fifth Floor, Bo ston, MA 0 2110-1301 USA. | |
20 | * | |
21 | * Please contact Or acle, 500 Oracle Par kway, Redw ood Shores , CA 94065 USA | |
22 | * or visi t www.orac le.com if you need a dditional informatio n or have any | |
23 | * questio ns. | |
24 | */ | |
25 | ||
26 | package co m.sun.cryp to.provide r; | |
27 | ||
28 | import jav a.util.Arr ays; | |
29 | import jav a.util.Loc ale; | |
30 | ||
31 | import jav a.security .*; | |
32 | import jav a.security .spec.*; | |
33 | import jav ax.crypto. *; | |
34 | import jav ax.crypto. spec.*; | |
35 | import jav ax.crypto. BadPadding Exception; | |
36 | ||
37 | /** | |
38 | * This cl ass repres ents the s ymmetric a lgorithms in its var ious modes | |
39 | * (<code> ECB</code> , <code>CF B</code>, <code>OFB< /code>, <c ode>CBC</c ode>, | |
40 | * <code>P CBC</code> , <code>CT R</code>, and <code> CTS</code> ) and | |
41 | * padding schemes ( <code>PKCS 5Padding</ code>, <co de>NoPaddi ng</code>, | |
42 | * <code>I SO10126Pad ding</code >). | |
43 | * | |
44 | * @author Gigi Anke ny | |
45 | * @author Jan Luehe | |
46 | * @see El ectronicCo deBook | |
47 | * @see Ci pherFeedba ck | |
48 | * @see Ou tputFeedba ck | |
49 | * @see Ci pherBlockC haining | |
50 | * @see PC BC | |
51 | * @see Co unterMode | |
52 | * @see Ci pherTextSt ealing | |
53 | */ | |
54 | ||
55 | final clas s CipherCo re { | |
56 | ||
57 | /* | |
58 | * int ernal buff er | |
59 | */ | |
60 | privat e byte[] b uffer = nu ll; | |
61 | ||
62 | /* | |
63 | * blo ck size of cipher in bytes | |
64 | */ | |
65 | privat e int bloc kSize = 0; | |
66 | ||
67 | /* | |
68 | * uni t size (nu mber of in put bytes that can b e processe d at a tim e) | |
69 | */ | |
70 | privat e int unit Bytes = 0; | |
71 | ||
72 | /* | |
73 | * ind ex of the content si ze left in the buffe r | |
74 | */ | |
75 | privat e int buff ered = 0; | |
76 | ||
77 | /* | |
78 | * min imum numbe r of bytes in the bu ffer requi red for | |
79 | * Fee dbackCiphe r.encryptF inal()/dec ryptFinal( ) call. | |
80 | * upd ate() must buffer th is many by tes before starting | |
81 | * to encrypt/de crypt data . | |
82 | * cur rently, on ly the fol lowing cas es have no n-zero val ues: | |
83 | * 1) CTS mode - due to it s special handling o n the last two block s | |
84 | * (th e last one may be in complete). | |
85 | * 2) GCM mode + decryptio n - due to its trail ing tag by tes | |
86 | */ | |
87 | privat e int minB ytes = 0; | |
88 | ||
89 | /* | |
90 | * num ber of byt es needed to make th e total in put length a multipl e | |
91 | * of the blocks ize (this is used in feedback mode, when the numbe r of | |
92 | * inp ut bytes t hat are pr ocessed at a time is different from the block | |
93 | * siz e) | |
94 | */ | |
95 | privat e int diff Blocksize = 0; | |
96 | ||
97 | /* | |
98 | * pad ding class | |
99 | */ | |
100 | privat e Padding padding = null; | |
101 | ||
102 | /* | |
103 | * int ernal ciph er engine | |
104 | */ | |
105 | privat e Feedback Cipher cip her = null ; | |
106 | ||
107 | /* | |
108 | * the cipher mo de | |
109 | */ | |
110 | privat e int ciph erMode = E CB_MODE; | |
111 | ||
112 | /* | |
113 | * are we encryp ting or de crypting? | |
114 | */ | |
115 | privat e boolean decrypting = false; | |
116 | ||
117 | /* | |
118 | * Blo ck Mode co nstants | |
119 | */ | |
120 | privat e static f inal int E CB_MODE = 0; | |
121 | privat e static f inal int C BC_MODE = 1; | |
122 | privat e static f inal int C FB_MODE = 2; | |
123 | privat e static f inal int O FB_MODE = 3; | |
124 | privat e static f inal int P CBC_MODE = 4; | |
125 | privat e static f inal int C TR_MODE = 5; | |
126 | privat e static f inal int C TS_MODE = 6; | |
127 | static final int GCM_MODE = 7; | |
128 | ||
129 | /* | |
130 | * var iables use d for perf orming the GCM (key+ iv) unique ness check . | |
131 | * To use GCM mo de safely, the ciphe r object m ust be re- initialize d | |
132 | * wit h a differ ent combin ation of k ey + iv va lues for e ach | |
133 | * enc ryption op eration. H owever, ch ecking all past key + iv value s | |
134 | * isn 't feasibl e. Thus, w e only do a per-inst ance check of the | |
135 | * key + iv valu es used in previous encryption . | |
136 | * For decryptio n operatio ns, no che cking is n ecessary. | |
137 | * NOT E: this ke y+iv check have to b e done ins ide Cipher Core class | |
138 | * sin ce CipherC ore class buffers po tential ta g bytes in GCM mode | |
139 | * and may not c all Galois CounterMod e when the re isn't s ufficient | |
140 | * inp ut to proc ess. | |
141 | */ | |
142 | privat e boolean requireRei nit = fals e; | |
143 | privat e byte[] l astEncKey = null; | |
144 | privat e byte[] l astEncIv = null; | |
145 | ||
146 | /** | |
147 | * Cre ates an in stance of CipherCore with defa ult ECB mo de and | |
148 | * PKC S5Padding. | |
149 | */ | |
150 | Cipher Core(Symme tricCipher impl, int blkSize) { | |
151 | bl ockSize = blkSize; | |
152 | un itBytes = blkSize; | |
153 | di ffBlocksiz e = blkSiz e; | |
154 | ||
155 | /* | |
156 | * The buffe r should b e usable f or all cip her mode a nd padding | |
157 | * schemes. Thus, it h as to be a t least (b lockSize+1 ) for CTS. | |
158 | * In decryp tion mode, it also h old the po ssible pad ding block . | |
159 | * / | |
160 | bu ffer = new byte[bloc kSize*2]; | |
161 | ||
162 | // set mode and paddin g | |
163 | ci pher = new Electroni cCodeBook( impl); | |
164 | pa dding = ne w PKCS5Pad ding(block Size); | |
165 | } | |
166 | ||
167 | /** | |
168 | * Set s the mode of this c ipher. | |
169 | * | |
170 | * @pa ram mode t he cipher mode | |
171 | * | |
172 | * @ex ception No SuchAlgori thmExcepti on if the requested cipher mod e does | |
173 | * not exist for this ciph er | |
174 | */ | |
175 | void s etMode(Str ing mode) throws NoS uchAlgorit hmExceptio n { | |
176 | if (mode == null) | |
177 | throw ne w NoSuchAl gorithmExc eption("nu ll mode"); | |
178 | ||
179 | St ring modeU pperCase = mode.toUp perCase(Lo cale.ENGLI SH); | |
180 | ||
181 | if (modeUppe rCase.equa ls("ECB")) { | |
182 | return; | |
183 | } | |
184 | ||
185 | Sy mmetricCip her rawImp l = cipher .getEmbedd edCipher() ; | |
186 | if (modeUppe rCase.equa ls("CBC")) { | |
187 | cipherMo de = CBC_M ODE; | |
188 | cipher = new Ciphe rBlockChai ning(rawIm pl); | |
189 | } else if (m odeUpperCa se.equals( "CTS")) { | |
190 | cipherMo de = CTS_M ODE; | |
191 | cipher = new Ciphe rTextSteal ing(rawImp l); | |
192 | minBytes = blockSi ze+1; | |
193 | padding = null; | |
194 | } else if (m odeUpperCa se.equals( "CTR")) { | |
195 | cipherMo de = CTR_M ODE; | |
196 | cipher = new Count erMode(raw Impl); | |
197 | unitByte s = 1; | |
198 | padding = null; | |
199 | } else if ( modeUpperC ase.equals ("GCM")) { | |
200 | // can o nly be use d for bloc k ciphers w/ 128-bit block siz e | |
201 | if (bloc kSize != 1 6) { | |
202 | thro w new NoSu chAlgorith mException | |
203 | ("GCM mode can only be used fo r AES ciph er"); | |
204 | } | |
205 | cipherMo de = GCM_M ODE; | |
206 | cipher = new Galoi sCounterMo de(rawImpl ); | |
207 | padding = null; | |
208 | } else if (m odeUpperCa se.startsW ith("CFB") ) { | |
209 | cipherMo de = CFB_M ODE; | |
210 | unitByte s = getNum OfUnit(mod e, "CFB".l ength(), b lockSize); | |
211 | cipher = new Ciphe rFeedback( rawImpl, u nitBytes); | |
212 | } else if (m odeUpperCa se.startsW ith("OFB") ) { | |
213 | cipherMo de = OFB_M ODE; | |
214 | unitByte s = getNum OfUnit(mod e, "OFB".l ength(), b lockSize); | |
215 | cipher = new Outpu tFeedback( rawImpl, u nitBytes); | |
216 | } else if (m odeUpperCa se.equals( "PCBC")) { | |
217 | cipherMo de = PCBC_ MODE; | |
218 | cipher = new PCBC( rawImpl); | |
219 | } | |
220 | el se { | |
221 | throw ne w NoSuchAl gorithmExc eption("Ci pher mode: " + mode | |
222 | + " not found "); | |
223 | } | |
224 | } | |
225 | ||
226 | /** | |
227 | * Ret urns the m ode of thi s cipher. | |
228 | * | |
229 | * @re turn the p arsed ciph er mode | |
230 | */ | |
231 | int ge tMode() { | |
232 | re turn ciphe rMode; | |
233 | } | |
234 | ||
235 | privat e static i nt getNumO fUnit(Stri ng mode, i nt offset, int block Size) | |
236 | th rows NoSuc hAlgorithm Exception { | |
237 | in t result = blockSize ; // use b lockSize a s default value | |
238 | if (mode.len gth() > of fset) { | |
239 | int numI nt; | |
240 | try { | |
241 | Inte ger num = Integer.va lueOf(mode .substring (offset)); | |
242 | numI nt = num.i ntValue(); | |
243 | resu lt = numIn t >> 3; | |
244 | } catch (NumberFor matExcepti on e) { | |
245 | thro w new NoSu chAlgorith mException | |
246 | ("Algorith m mode: " + mode + " not imple mented"); | |
247 | } | |
248 | if ((num Int % 8 != 0) || (re sult > blo ckSize)) { | |
249 | thro w new NoSu chAlgorith mException | |
250 | ("Invalid algorithm mode: " + mode); | |
251 | } | |
252 | } | |
253 | re turn resul t; | |
254 | } | |
255 | ||
256 | ||
257 | /** | |
258 | * Set s the padd ing mechan ism of thi s cipher. | |
259 | * | |
260 | * @pa ram paddin g the padd ing mechan ism | |
261 | * | |
262 | * @ex ception No SuchPaddin gException if the re quested pa dding mech anism | |
263 | * doe s not exis t | |
264 | */ | |
265 | void s etPadding( String pad dingScheme ) | |
266 | th rows NoSuc hPaddingEx ception | |
267 | { | |
268 | if (paddingS cheme == n ull) { | |
269 | throw ne w NoSuchPa ddingExcep tion("null padding") ; | |
270 | } | |
271 | if (paddingS cheme.equa lsIgnoreCa se("NoPadd ing")) { | |
272 | padding = null; | |
273 | } else if (p addingSche me.equalsI gnoreCase( "ISO10126P adding")) { | |
274 | padding = new ISO1 0126Paddin g(blockSiz e); | |
275 | } else if (! paddingSch eme.equals IgnoreCase ("PKCS5Pad ding")) { | |
276 | throw ne w NoSuchPa ddingExcep tion("Padd ing: " + p addingSche me | |
277 | + " n ot impleme nted"); | |
278 | } | |
279 | if ((padding != null) && | |
280 | ((cipher Mode == CT R_MODE) || (cipherMo de == CTS_ MODE) | |
281 | || (cip herMode == GCM_MODE) )) { | |
282 | padding = null; | |
283 | String m odeStr = n ull; | |
284 | switch ( cipherMode ) { | |
285 | case CTR _MODE: | |
286 | mode Str = "CTR "; | |
287 | brea k; | |
288 | case GCM _MODE: | |
289 | mode Str = "GCM "; | |
290 | brea k; | |
291 | case CTS _MODE: | |
292 | mode Str = "CTS "; | |
293 | brea k; | |
294 | default: | |
295 | // s hould neve r happen | |
296 | } | |
297 | if (mode Str != nul l) { | |
298 | thro w new NoSu chPaddingE xception | |
299 | (modeStr + " mode mu st be used with NoPa dding"); | |
300 | } | |
301 | } | |
302 | } | |
303 | ||
304 | /** | |
305 | * Ret urns the l ength in b ytes that an output buffer wou ld need to be in | |
306 | * ord er to hold the resul t of the n ext <code> update</co de> or | |
307 | * <co de>doFinal </code> op eration, g iven the i nput lengt h | |
308 | * <co de>inputLe n</code> ( in bytes). | |
309 | * | |
310 | * <p> This call takes into account a ny unproce ssed (buff ered) data from a | |
311 | * pre vious <cod e>update</ code> call , padding, and AEAD tagging. | |
312 | * | |
313 | * <p> The actual output le ngth of th e next <co de>update< /code> or | |
314 | * <co de>doFinal </code> ca ll may be smaller th an the len gth return ed by | |
315 | * thi s method. | |
316 | * | |
317 | * @pa ram inputL en the inp ut length (in bytes) | |
318 | * | |
319 | * @re turn the r equired ou tput buffe r size (in bytes) | |
320 | */ | |
321 | int ge tOutputSiz e(int inpu tLen) { | |
322 | // estimate based on t he maximum | |
323 | re turn getOu tputSizeBy Operation( inputLen, true); | |
324 | } | |
325 | ||
326 | privat e int getO utputSizeB yOperation (int input Len, boole an isDoFin al) { | |
327 | in t totalLen = Math.ad dExact(buf fered, cip her.getBuf feredLengt h()); | |
328 | to talLen = M ath.addExa ct(totalLe n, inputLe n); | |
329 | sw itch (ciph erMode) { | |
330 | ca se GCM_MOD E: | |
331 | if (isDo Final) { | |
332 | int tagLen = ( (GaloisCou nterMode) cipher).ge tTagLen(); | |
333 | if ( !decryptin g) { | |
334 | totalLen = Math.addE xact(total Len, tagLe n); | |
335 | } el se { | |
336 | totalLen - = tagLen; | |
337 | } | |
338 | } | |
339 | if (tota lLen < 0) { | |
340 | tota lLen = 0; | |
341 | } | |
342 | break; | |
343 | de fault: | |
344 | if (padd ing != nul l && !decr ypting) { | |
345 | if ( unitBytes != blockSi ze) { | |
346 | if (totalL en < diffB locksize) { | |
347 | totalL en = diffB locksize; | |
348 | } else { | |
349 | int re sidue = (t otalLen - diffBlocks ize) % blo ckSize; | |
350 | totalL en = Math. addExact(t otalLen, ( blockSize - residue) ); | |
351 | } | |
352 | } el se { | |
353 | totalLen = Math.addE xact(total Len, paddi ng.padLeng th(totalLe n)); | |
354 | } | |
355 | } | |
356 | break; | |
357 | } | |
358 | re turn total Len; | |
359 | } | |
360 | ||
361 | /** | |
362 | * Ret urns the i nitializat ion vector (IV) in a new buffe r. | |
363 | * | |
364 | * <p> This is us eful in th e case whe re a rando m IV has b een create d | |
365 | * (se e <a href = "#init"> init</a>), | |
366 | * or in the con text of pa ssword-bas ed encrypt ion or | |
367 | * dec ryption, w here the I V is deriv ed from a user-provi ded passwo rd. | |
368 | * | |
369 | * @re turn the i nitializat ion vector in a new buffer, or null if t he | |
370 | * und erlying al gorithm do es not use an IV, or if the IV has not y et | |
371 | * bee n set. | |
372 | */ | |
373 | byte[] getIV() { | |
374 | by te[] iv = cipher.get IV(); | |
375 | re turn (iv = = null) ? null : iv. clone(); | |
376 | } | |
377 | ||
378 | /** | |
379 | * Ret urns the p arameters used with this ciphe r. | |
380 | * | |
381 | * <p> The return ed paramet ers may be the same that were used to in itialize | |
382 | * thi s cipher, or may con tain the d efault set of parame ters or a set of | |
383 | * ran domly gene rated para meters use d by the u nderlying cipher | |
384 | * imp lementatio n (provide d that the underlyin g cipher i mplementat ion | |
385 | * use s a defaul t set of p arameters or creates new param eters if i t needs | |
386 | * par ameters bu t was not initialize d with any ). | |
387 | * | |
388 | * @re turn the p arameters used with this ciphe r, or null if this c ipher | |
389 | * doe s not use any parame ters. | |
390 | */ | |
391 | Algori thmParamet ers getPar ameters(St ring algNa me) { | |
392 | if (cipherMo de == ECB_ MODE) { | |
393 | return n ull; | |
394 | } | |
395 | Al gorithmPar ameters pa rams = nul l; | |
396 | Al gorithmPar ameterSpec spec; | |
397 | by te[] iv = getIV(); | |
398 | if (iv == nu ll) { | |
399 | // gener ate spec u sing defau lt value | |
400 | if (ciph erMode == GCM_MODE) { | |
401 | iv = new byte[ GaloisCoun terMode.DE FAULT_IV_L EN]; | |
402 | } else { | |
403 | iv = new byte[ blockSize] ; | |
404 | } | |
405 | SunJCE.g etRandom() .nextBytes (iv); | |
406 | } | |
407 | if (cipherMo de == GCM_ MODE) { | |
408 | algName = "GCM"; | |
409 | spec = n ew GCMPara meterSpec | |
410 | (((G aloisCount erMode) ci pher).getT agLen()*8, iv); | |
411 | } else { | |
412 | if (algNa me.equals( "RC2")) { | |
413 | RC2Cr ypt rawImp l = (RC2Cr ypt) ciphe r.getEmbed dedCipher( ); | |
414 | spec = new RC2P arameterSp ec | |
415 | ( rawImpl.ge tEffective KeyBits(), iv); | |
416 | } else { | |
417 | spec = new IvPa rameterSpe c(iv); | |
418 | } | |
419 | } | |
420 | tr y { | |
421 | params = Algorithm Parameters .getInstan ce(algName , | |
422 | SunJCE.get Instance() ); | |
423 | params.i nit(spec); | |
424 | } catch (NoS uchAlgorit hmExceptio n nsae) { | |
425 | // shoul d never ha ppen | |
426 | throw ne w RuntimeE xception(" Cannot fin d " + algN ame + | |
427 | " Al gorithmPar ameters im plementati on in SunJ CE provide r"); | |
428 | } catch (Inv alidParame terSpecExc eption ips e) { | |
429 | // shoul d never ha ppen | |
430 | throw ne w RuntimeE xception(s pec.getCla ss() + " n ot support ed"); | |
431 | } | |
432 | re turn param s; | |
433 | } | |
434 | ||
435 | /** | |
436 | * Ini tializes t his cipher with a ke y and a so urce of ra ndomness. | |
437 | * | |
438 | * <p> The cipher is initia lized for one of the following four oper ations: | |
439 | * enc ryption, d ecryption, key wrapp ing or key unwrappin g, dependi ng on | |
440 | * the value of <code>opmo de</code>. | |
441 | * | |
442 | * <p> If this ci pher requi res an ini tializatio n vector ( IV), it wi ll get | |
443 | * it from <code >random</c ode>. | |
444 | * Thi s behaviou r should o nly be use d in encry ption or k ey wrappin g | |
445 | * mod e, however . | |
446 | * Whe n initiali zing a cip her that r equires an IV for de cryption o r | |
447 | * key unwrappin g, the IV | |
448 | * (sa me IV that was used for encryp tion or ke y wrapping ) must be provided | |
449 | * exp licitly as a | |
450 | * par ameter, in order to get the co rrect resu lt. | |
451 | * | |
452 | * <p> This metho d also cle ans existi ng buffer and other related st ate | |
453 | * inf ormation. | |
454 | * | |
455 | * @pa ram opmode the opera tion mode of this ci pher (this is one of | |
456 | * the following : | |
457 | * <co de>ENCRYPT _MODE</cod e>, <code> DECRYPT_MO DE</code>, | |
458 | * <co de>WRAP_MO DE</code> or <code>U NWRAP_MODE </code>) | |
459 | * @param k ey the PW key | |
460 | * @pa ram random the sourc e of rando mness | |
461 | * | |
462 | * @ex ception In validKeyEx ception if the given key is in appropriat e for | |
463 | * ini tializing this ciphe r | |
464 | */ | |
465 | void i nit(int op mode, Key key, Secur eRandom ra ndom) | |
466 | throws I nvalidKeyE xception { | |
467 | tr y { | |
468 | init(opm ode, key, (Algorithm ParameterS pec)null, random); | |
469 | } catch (Inv alidAlgori thmParamet erExceptio n e) { | |
470 | throw ne w InvalidK eyExceptio n(e.getMes sage()); | |
471 | } | |
472 | } | |
473 | ||
474 | /** | |
475 | * Ini tializes t his cipher with a ke y, a set o f | |
476 | * alg orithm par ameters, a nd a sourc e of rando mness. | |
477 | * | |
478 | * <p> The cipher is initia lized for one of the following four oper ations: | |
479 | * enc ryption, d ecryption, key wrapp ing or key unwrappin g, dependi ng on | |
480 | * the value of <code>opmo de</code>. | |
481 | * | |
482 | * <p> If this ci pher (incl uding its underlying feedback or padding scheme) | |
483 | * req uires any random byt es, it wil l get them from <cod e>random</ code>. | |
484 | * | |
485 | * @pa ram opmode the opera tion mode of this ci pher (this is one of | |
486 | * the following : | |
487 | * <co de>ENCRYPT _MODE</cod e>, <code> DECRYPT_MO DE</code>, | |
488 | * <co de>WRAP_MO DE</code> or <code>U NWRAP_MODE </code>) | |
489 | * @pa ram key th e encrypti on key | |
490 | * @pa ram params the algor ithm param eters | |
491 | * @pa ram random the sourc e of rando mness | |
492 | * | |
493 | * @ex ception In validKeyEx ception if the given key is in appropriat e for | |
494 | * ini tializing this ciphe r | |
495 | * @ex ception In validAlgor ithmParame terExcepti on if the given algo rithm | |
496 | * par ameters ar e inapprop riate for this ciphe r | |
497 | */ | |
498 | void i nit(int op mode, Key key, Algor ithmParame terSpec pa rams, | |
499 | SecureRa ndom rando m) | |
500 | throws I nvalidKeyE xception, InvalidAlg orithmPara meterExcep tion { | |
501 | de crypting = (opmode = = Cipher.D ECRYPT_MOD E) | |
502 | || (opmode = = Cipher.U NWRAP_MODE ); | |
503 | ||
504 | by te[] keyBy tes = getK eyBytes(ke y); | |
505 | in t tagLen = -1; | |
506 | by te[] ivByt es = null; | |
507 | if (params ! = null) { | |
508 | if (ciph erMode == GCM_MODE) { | |
509 | if ( params ins tanceof GC MParameter Spec) { | |
510 | tagLen = ( (GCMParame terSpec)pa rams).getT Len(); | |
511 | if (tagLen < 96 || t agLen > 12 8 || ((tag Len & 0x07 ) != 0)) { | |
512 | throw new Invali dAlgorithm ParameterE xception | |
513 | (" Unsupporte d TLen val ue; must b e one of " + | |
514 | " {128, 120, 112, 104, 96}"); | |
515 | } | |
516 | tagLen = t agLen >> 3 ; | |
517 | ivBytes = ((GCMParam eterSpec)p arams).get IV(); | |
518 | } el se { | |
519 | throw new InvalidAlg orithmPara meterExcep tion | |
520 | ("Unsu pported pa rameter: " + params) ; | |
521 | } | |
522 | } else { | |
523 | if ( params ins tanceof Iv ParameterS pec) { | |
524 | ivBytes = ((IvParame terSpec)pa rams).getI V(); | |
525 | if ((ivByt es == null ) || (ivBy tes.length != blockS ize)) { | |
526 | throw new Invali dAlgorithm ParameterE xception | |
527 | (" Wrong IV l ength: mus t be " + b lockSize + | |
528 | " bytes lon g"); | |
529 | } | |
530 | } el se if (par ams instan ceof RC2Pa rameterSpe c) { | |
531 | ivBytes = ((RC2Param eterSpec)p arams).get IV(); | |
532 | if ((ivByt es != null ) && (ivBy tes.length != blockS ize)) { | |
533 | throw new Invali dAlgorithm ParameterE xception | |
534 | (" Wrong IV l ength: mus t be " + b lockSize + | |
535 | " bytes lon g"); | |
536 | } | |
537 | } el se { | |
538 | throw new InvalidAlg orithmPara meterExcep tion | |
539 | ("Unsu pported pa rameter: " + params) ; | |
540 | } | |
541 | } | |
542 | } | |
543 | if (cipherMo de == ECB_ MODE) { | |
544 | if (ivBy tes != nul l) { | |
545 | thro w new Inva lidAlgorit hmParamete rException | |
546 | (" ECB mode c annot use IV"); | |
547 | } | |
548 | } else if (i vBytes == null) { | |
549 | if (decr ypting) { | |
550 | thro w new Inva lidAlgorit hmParamete rException ("Paramete rs " | |
551 | + "missin g"); | |
552 | } | |
553 | ||
554 | if (rand om == null ) { | |
555 | rand om = SunJC E.getRando m(); | |
556 | } | |
557 | if (ciph erMode == GCM_MODE) { | |
558 | ivBy tes = new byte[Galoi sCounterMo de.DEFAULT _IV_LEN]; | |
559 | } else { | |
560 | ivBy tes = new byte[block Size]; | |
561 | } | |
562 | random.n extBytes(i vBytes); | |
563 | } | |
564 | ||
565 | bu ffered = 0 ; | |
566 | di ffBlocksiz e = blockS ize; | |
567 | ||
568 | St ring algor ithm = key .getAlgori thm(); | |
569 | ||
570 | // GCM mode needs addi tional han dling | |
571 | if (cipherMo de == GCM_ MODE) { | |
572 | if(tagLe n == -1) { | |
573 | tagL en = Galoi sCounterMo de.DEFAULT _TAG_LEN; | |
574 | } | |
575 | if (decr ypting) { | |
576 | minB ytes = tag Len; | |
577 | } else { | |
578 | // c heck key+i v for encr yption in GCM mode | |
579 | requ ireReinit = | |
580 | Arrays.equ als(ivByte s, lastEnc Iv) && | |
581 | MessageDig est.isEqua l(keyBytes , lastEncK ey); | |
582 | if ( requireRei nit) { | |
583 | throw new InvalidAlg orithmPara meterExcep tion | |
584 | ("Cann ot reuse i v for GCM encryption "); | |
585 | } | |
586 | last EncIv = iv Bytes; | |
587 | last EncKey = k eyBytes; | |
588 | } | |
589 | ((Galois CounterMod e) cipher) .init | |
590 | (dec rypting, a lgorithm, keyBytes, ivBytes, t agLen); | |
591 | } else { | |
592 | cipher.i nit(decryp ting, algo rithm, key Bytes, ivB ytes); | |
593 | } | |
594 | // skip chec king key+i v from now on until after doFi nal() | |
595 | re quireReini t = false; | |
596 | } | |
597 | ||
598 | void i nit(int op mode, Key key, Algor ithmParame ters param s, | |
599 | Secure Random ran dom) | |
600 | th rows Inval idKeyExcep tion, Inva lidAlgorit hmParamete rException { | |
601 | Al gorithmPar ameterSpec spec = nu ll; | |
602 | St ring param Type = nul l; | |
603 | if (params ! = null) { | |
604 | try { | |
605 | if ( cipherMode == GCM_MO DE) { | |
606 | paramType = "GCM"; | |
607 | spec = par ams.getPar ameterSpec (GCMParame terSpec.cl ass); | |
608 | } el se { | |
609 | // NOTE: R C2 paramet ers are al ways handl ed through | |
610 | // init(.. ., Algorit hmParamete rSpec,...) method, s o | |
611 | // we can assume IvP arameterSp ec type he re. | |
612 | paramType = "IV"; | |
613 | spec = par ams.getPar ameterSpec (IvParamet erSpec.cla ss); | |
614 | } | |
615 | } catch (InvalidPa rameterSpe cException ipse) { | |
616 | thro w new Inva lidAlgorit hmParamete rException | |
617 | ("Wrong pa rameter ty pe: " + pa ramType + " expected "); | |
618 | } | |
619 | } | |
620 | in it(opmode, key, spec , random); | |
621 | } | |
622 | ||
623 | /** | |
624 | * Ret urn the ke y bytes of the speci fied key. Throw an I nvalidKeyE xception | |
625 | * if the key is not usabl e. | |
626 | */ | |
627 | static byte[] ge tKeyBytes( Key key) t hrows Inva lidKeyExce ption { | |
628 | if (key == n ull) { | |
629 | throw ne w InvalidK eyExceptio n("No key given"); | |
630 | } | |
631 | // note: key .getFormat () may ret urn null | |
632 | if (!"RAW".e qualsIgnor eCase(key. getFormat( ))) { | |
633 | throw ne w InvalidK eyExceptio n("Wrong f ormat: RAW bytes nee ded"); | |
634 | } | |
635 | by te[] keyBy tes = key. getEncoded (); | |
636 | if (keyBytes == null) { | |
637 | throw ne w InvalidK eyExceptio n("RAW key bytes mis sing"); | |
638 | } | |
639 | re turn keyBy tes; | |
640 | } | |
641 | ||
642 | ||
643 | /** | |
644 | * Con tinues a m ultiple-pa rt encrypt ion or dec ryption op eration | |
645 | * (de pending on how this cipher was initializ ed), proce ssing anot her data | |
646 | * par t. | |
647 | * | |
648 | * <p> The first <code>inpu tLen</code > bytes in the <code >input</co de> | |
649 | * buf fer, start ing at <co de>inputOf fset</code >, are pro cessed, an d the | |
650 | * res ult is sto red in a n ew buffer. | |
651 | * | |
652 | * @pa ram input the input buffer | |
653 | * @pa ram inputO ffset the offset in <code>inpu t</code> w here the i nput | |
654 | * sta rts | |
655 | * @pa ram inputL en the inp ut length | |
656 | * | |
657 | * @re turn the n ew buffer with the r esult | |
658 | * | |
659 | * @ex ception Il legalState Exception if this ci pher is in a wrong s tate | |
660 | * (e. g., has no t been ini tialized) | |
661 | */ | |
662 | byte[] update(by te[] input , int inpu tOffset, i nt inputLe n) { | |
663 | if (requireR einit) { | |
664 | throw ne w IllegalS tateExcept ion | |
665 | ("Mu st use eit her differ ent key or iv for GC M encrypti on"); | |
666 | } | |
667 | ||
668 | by te[] outpu t = null; | |
669 | tr y { | |
670 | output = new byte[ getOutputS izeByOpera tion(input Len, false )]; | |
671 | int len = update(i nput, inpu tOffset, i nputLen, o utput, | |
672 | 0 ); | |
673 | if (len == output. length) { | |
674 | retu rn output; | |
675 | } else { | |
676 | retu rn Arrays. copyOf(out put, len); | |
677 | } | |
678 | } catch (Sho rtBufferEx ception e) { | |
679 | // shoul d never ha ppen | |
680 | throw ne w Provider Exception( "Unexpecte d exceptio n", e); | |
681 | } | |
682 | } | |
683 | ||
684 | /** | |
685 | * Con tinues a m ultiple-pa rt encrypt ion or dec ryption op eration | |
686 | * (de pending on how this cipher was initializ ed), proce ssing anot her data | |
687 | * par t. | |
688 | * | |
689 | * <p> The first <code>inpu tLen</code > bytes in the <code >input</co de> | |
690 | * buf fer, start ing at <co de>inputOf fset</code >, are pro cessed, an d the | |
691 | * res ult is sto red in the <code>out put</code> buffer, s tarting at | |
692 | * <co de>outputO ffset</cod e>. | |
693 | * | |
694 | * @pa ram input the input buffer | |
695 | * @pa ram inputO ffset the offset in <code>inpu t</code> w here the i nput | |
696 | * sta rts | |
697 | * @pa ram inputL en the inp ut length | |
698 | * @pa ram output the buffe r for the result | |
699 | * @pa ram output Offset the offset in <code>out put</code> where the result | |
700 | * is stored | |
701 | * | |
702 | * @re turn the n umber of b ytes store d in <code >output</c ode> | |
703 | * | |
704 | * @ex ception Sh ortBufferE xception i f the give n output b uffer is t oo small | |
705 | * to hold the r esult | |
706 | */ | |
707 | int up date(byte[ ] input, i nt inputOf fset, int inputLen, byte[] out put, | |
708 | int o utputOffse t) throws ShortBuffe rException { | |
709 | if (requireR einit) { | |
710 | throw ne w IllegalS tateExcept ion | |
711 | ("Mu st use eit her differ ent key or iv for GC M encrypti on"); | |
712 | } | |
713 | ||
714 | // figure ou t how much can be se nt to cryp to functio n | |
715 | in t len = Ma th.addExac t(buffered , inputLen ); | |
716 | le n -= minBy tes; | |
717 | if (padding != null && decryptin g) { | |
718 | // do no t include the paddin g bytes wh en decrypt ing | |
719 | len -= b lockSize; | |
720 | } | |
721 | // do not co unt the tr ailing byt es which d o not make up a unit | |
722 | le n = (len > 0 ? (len - (len % u nitBytes)) : 0); | |
723 | ||
724 | // check out put buffer capacity | |
725 | if ((output == null) | | | |
726 | ((output .length - outputOffs et) < len) ) { | |
727 | throw ne w ShortBuf ferExcepti on("Output buffer mu st be " | |
728 | + "(at least) " + len | |
729 | + " byt es long"); | |
730 | } | |
731 | ||
732 | in t outLen = 0; | |
733 | if (len != 0 ) { // the re is some work to d o | |
734 | if ((inp ut == outp ut) | |
735 | && (outputOff set - inpu tOffset < inputLen) | |
736 | && (inputOffs et - outpu tOffset < buffer.len gth)) { | |
737 | // c opy 'input ' out to a void its c ontent bei ng | |
738 | // o verwritten premature ly. | |
739 | inpu t = Arrays .copyOfRan ge(input, inputOffse t, | |
740 | Math.addEx act(inputO ffset, inp utLen)); | |
741 | inpu tOffset = 0; | |
742 | } | |
743 | if (len <= buffere d) { | |
744 | // a ll to-be-p rocessed d ata are fr om 'buffer ' | |
745 | if ( decrypting ) { | |
746 | outLen = c ipher.decr ypt(buffer , 0, len, output, ou tputOffset ); | |
747 | } el se { | |
748 | outLen = c ipher.encr ypt(buffer , 0, len, output, ou tputOffset ); | |
749 | } | |
750 | buff ered -= le n; | |
751 | if ( buffered ! = 0) { | |
752 | System.arr aycopy(buf fer, len, buffer, 0, buffered) ; | |
753 | } | |
754 | } else { // len > buffered | |
755 | int inputConsu med = len - buffered ; | |
756 | int temp; | |
757 | if ( buffered > 0) { | |
758 | int buffer Capacity = buffer.le ngth - buf fered; | |
759 | if (buffer Capacity ! = 0) { | |
760 | temp = Math.min( bufferCapa city, inpu tConsumed) ; | |
761 | if (un itBytes != blockSize ) { | |
762 | te mp -= (Mat h.addExact (buffered, temp) % u nitBytes); | |
763 | } | |
764 | System .arraycopy (input, in putOffset, buffer, b uffered, t emp); | |
765 | inputO ffset = Ma th.addExac t(inputOff set, temp) ; | |
766 | inputC onsumed -= temp; | |
767 | inputL en -= temp ; | |
768 | buffer ed = Math. addExact(b uffered, t emp); | |
769 | } | |
770 | // process 'buffer' | |
771 | if (decryp ting) { | |
772 | outLe n = cipher .decrypt(b uffer, 0, buffered, output, ou tputOffset ); | |
773 | } else { | |
774 | outLe n = cipher .encrypt(b uffer, 0, buffered, output, ou tputOffset ); | |
775 | } | |
776 | outputOffs et = Math. addExact(o utputOffse t, outLen) ; | |
777 | buffered = 0; | |
778 | } | |
779 | if ( inputConsu med > 0) { // still has input to process | |
780 | if (decryp ting) { | |
781 | outLen += cipher .decrypt(i nput, inpu tOffset, i nputConsum ed, | |
782 | ou tput, outp utOffset); | |
783 | } else { | |
784 | outLen += cipher .encrypt(i nput, inpu tOffset, i nputConsum ed, | |
785 | ou tput, outp utOffset); | |
786 | } | |
787 | inputOffse t += input Consumed; | |
788 | inputLen - = inputCon sumed; | |
789 | } | |
790 | } | |
791 | // Let's keep trac k of how m any bytes are needed to make | |
792 | // the t otal input length a multiple o f blocksiz e when | |
793 | // paddi ng is appl ied | |
794 | if (unit Bytes != b lockSize) { | |
795 | if ( len < diff Blocksize) { | |
796 | diffBlocks ize -= len ; | |
797 | } el se { | |
798 | diffBlocks ize = bloc kSize - | |
799 | ((len - diffBloc ksize) % b lockSize); | |
800 | } | |
801 | } | |
802 | } | |
803 | // Store rem aining inp ut into 'b uffer' aga in | |
804 | if (inputLen > 0) { | |
805 | System.a rraycopy(i nput, inpu tOffset, b uffer, buf fered, | |
806 | i nputLen); | |
807 | buffered = Math.ad dExact(buf fered, inp utLen); | |
808 | } | |
809 | re turn outLe n; | |
810 | } | |
811 | ||
812 | /** | |
813 | * Enc rypts or d ecrypts da ta in a si ngle-part operation, | |
814 | * or finishes a multiple- part opera tion. | |
815 | * The data is e ncrypted o r decrypte d, dependi ng on how this ciphe r was | |
816 | * ini tialized. | |
817 | * | |
818 | * <p> The first <code>inpu tLen</code > bytes in the <code >input</co de> | |
819 | * buf fer, start ing at <co de>inputOf fset</code >, and any input byt es that | |
820 | * may have been buffered during a p revious <c ode>update </code> op eration, | |
821 | * are processed , with pad ding (if r equested) being appl ied. | |
822 | * The result is stored in a new buf fer. | |
823 | * | |
824 | * <p> The cipher is reset to its ini tial state (uninitia lized) aft er this | |
825 | * cal l. | |
826 | * | |
827 | * @pa ram input the input buffer | |
828 | * @pa ram inputO ffset the offset in <code>inpu t</code> w here the i nput | |
829 | * sta rts | |
830 | * @pa ram inputL en the inp ut length | |
831 | * | |
832 | * @re turn the n ew buffer with the r esult | |
833 | * | |
834 | * @ex ception Il legalBlock SizeExcept ion if thi s cipher i s a block cipher, | |
835 | * no padding ha s been req uested (on ly in encr yption mod e), and th e total | |
836 | * inp ut length of the dat a processe d by this cipher is not a mult iple of | |
837 | * blo ck size | |
838 | * @ex ception Ba dPaddingEx ception if this ciph er is in d ecryption mode, | |
839 | * and (un)paddi ng has bee n requeste d, but the decrypted data is n ot | |
840 | * bou nded by th e appropri ate paddin g bytes | |
841 | */ | |
842 | byte[] doFinal(b yte[] inpu t, int inp utOffset, int inputL en) | |
843 | th rows Illeg alBlockSiz eException , BadPaddi ngExceptio n { | |
844 | by te[] outpu t = null; | |
845 | tr y { | |
846 | output = new byte[ getOutputS izeByOpera tion(input Len, true) ]; | |
847 | int len = doFinal( input, inp utOffset, inputLen, output, 0) ; | |
848 | if (len < output.l ength) { | |
849 | retu rn Arrays. copyOf(out put, len); | |
850 | } else { | |
851 | retu rn output; | |
852 | } | |
853 | } catch (Sho rtBufferEx ception e) { | |
854 | // never thrown | |
855 | throw ne w Provider Exception( "Unexpecte d exceptio n", e); | |
856 | } | |
857 | } | |
858 | ||
859 | /** | |
860 | * Enc rypts or d ecrypts da ta in a si ngle-part operation, | |
861 | * or finishes a multiple- part opera tion. | |
862 | * The data is e ncrypted o r decrypte d, dependi ng on how this ciphe r was | |
863 | * ini tialized. | |
864 | * | |
865 | * <p> The first <code>inpu tLen</code > bytes in the <code >input</co de> | |
866 | * buf fer, start ing at <co de>inputOf fset</code >, and any input byt es that | |
867 | * may have been buffered during a p revious <c ode>update </code> op eration, | |
868 | * are processed , with pad ding (if r equested) being appl ied. | |
869 | * The result is stored in the <code >output</c ode> buffe r, startin g at | |
870 | * <co de>outputO ffset</cod e>. | |
871 | * | |
872 | * <p> The cipher is reset to its ini tial state (uninitia lized) aft er this | |
873 | * cal l. | |
874 | * | |
875 | * @pa ram input the input buffer | |
876 | * @pa ram inputO ffset the offset in <code>inpu t</code> w here the i nput | |
877 | * sta rts | |
878 | * @pa ram inputL en the inp ut length | |
879 | * @pa ram output the buffe r for the result | |
880 | * @pa ram output Offset the offset in <code>out put</code> where the result | |
881 | * is stored | |
882 | * | |
883 | * @re turn the n umber of b ytes store d in <code >output</c ode> | |
884 | * | |
885 | * @ex ception Il legalBlock SizeExcept ion if thi s cipher i s a block cipher, | |
886 | * no padding ha s been req uested (on ly in encr yption mod e), and th e total | |
887 | * inp ut length of the dat a processe d by this cipher is not a mult iple of | |
888 | * blo ck size | |
889 | * @ex ception Sh ortBufferE xception i f the give n output b uffer is t oo small | |
890 | * to hold the r esult | |
891 | * @ex ception Ba dPaddingEx ception if this ciph er is in d ecryption mode, | |
892 | * and (un)paddi ng has bee n requeste d, but the decrypted data is n ot | |
893 | * bou nded by th e appropri ate paddin g bytes | |
894 | */ | |
895 | int do Final(byte [] input, int inputO ffset, int inputLen, byte[] ou tput, | |
896 | int outputOffs et) | |
897 | th rows Illeg alBlockSiz eException , ShortBuf ferExcepti on, | |
898 | BadPa ddingExcep tion { | |
899 | if (requireR einit) { | |
900 | throw ne w IllegalS tateExcept ion | |
901 | ("Mu st use eit her differ ent key or iv for GC M encrypti on"); | |
902 | } | |
903 | ||
904 | in t estOutSi ze = getOu tputSizeBy Operation( inputLen, true); | |
905 | // check out put buffer capacity. | |
906 | // if we are decryptin g with pad ding appli ed, we can perform t his | |
907 | // check onl y after we have dete rmined how many padd ing bytes there | |
908 | // are. | |
909 | in t outputCa pacity = o utput.leng th - outpu tOffset; | |
910 | in t minOutSi ze = (decr ypting? (e stOutSize - blockSiz e):estOutS ize); | |
911 | if ((output == null) | | (outputC apacity < minOutSize )) { | |
912 | throw ne w ShortBuf ferExcepti on("Output buffer mu st be " | |
913 | + "( at least) " + minOut Size + " b ytes long" ); | |
914 | } | |
915 | ||
916 | // calculate total inp ut length | |
917 | in t len = Ma th.addExac t(buffered , inputLen ); | |
918 | ||
919 | // calculate padding l ength | |
920 | in t totalLen = Math.ad dExact(len , cipher.g etBuffered Length()); | |
921 | in t paddingL en = 0; | |
922 | // will the total inpu t length b e a multip le of bloc kSize? | |
923 | if (unitByte s != block Size) { | |
924 | if (tota lLen < dif fBlocksize ) { | |
925 | padd ingLen = d iffBlocksi ze - total Len; | |
926 | } else { | |
927 | padd ingLen = b lockSize - | |
928 | ((totalLen - diffBlo cksize) % blockSize) ; | |
929 | } | |
930 | } else if (p adding != null) { | |
931 | paddingL en = paddi ng.padLeng th(totalLe n); | |
932 | } | |
933 | ||
934 | if (decrypti ng && (pad ding != nu ll) && | |
935 | (padding Len > 0) & & (padding Len != blo ckSize)) { | |
936 | throw ne w IllegalB lockSizeEx ception | |
937 | ("In put length must be m ultiple of " + block Size + | |
938 | " w hen decryp ting with padded cip her"); | |
939 | } | |
940 | ||
941 | /* | |
942 | * prepare t he final i nput, asse mble a new buffer if any | |
943 | * of the fo llowing is true: | |
944 | * - 'input ' and 'out put' are t he same bu ffer | |
945 | * - there are intern ally buffe red bytes | |
946 | * - doing encryption and paddi ng is need ed | |
947 | * / | |
948 | by te[] final Buf = inpu t; | |
949 | in t finalOff set = inpu tOffset; | |
950 | in t finalBuf Len = inpu tLen; | |
951 | if ((buffere d != 0) || (!decrypt ing && pad ding != nu ll) || | |
952 | ((input == output) | |
953 | && (ou tputOffset - inputOf fset < inp utLen) | |
954 | && (in putOffset - outputOf fset < buf fer.length ))) { | |
955 | if (decr ypting || padding == null) { | |
956 | padd ingLen = 0 ; | |
957 | } | |
958 | finalBuf = new byt e[Math.add Exact(len, paddingLe n)]; | |
959 | finalOff set = 0; | |
960 | if (buff ered != 0) { | |
961 | Syst em.arrayco py(buffer, 0, finalB uf, 0, buf fered); | |
962 | } | |
963 | if (inpu tLen != 0) { | |
964 | Syst em.arrayco py(input, inputOffse t, finalBu f, | |
965 | buffere d, inputLe n); | |
966 | } | |
967 | if (padd ingLen != 0) { | |
968 | padd ing.padWit hLen(final Buf, Math. addExact(b uffered, i nputLen), paddingLen ); | |
969 | } | |
970 | finalBuf Len = fina lBuf.lengt h; | |
971 | } | |
972 | in t outLen = 0; | |
973 | if (decrypti ng) { | |
974 | // if th e size of specified output buf fer is les s than | |
975 | // the l ength of t he cipher text, then the curre nt | |
976 | // conte nt of ciph er has to be preserv ed in orde r for | |
977 | // users to retry the call w ith a larg er buffer in the | |
978 | // case of ShortBu fferExcept ion. | |
979 | if (outp utCapacity < estOutS ize) { | |
980 | ciph er.save(); | |
981 | } | |
982 | // creat e temporar y output b uffer so t hat only " real" | |
983 | // data bytes are passed to user's out put buffer . | |
984 | byte[] o utWithPadd ing = new byte[estOu tSize]; | |
985 | outLen = finalNoPa dding(fina lBuf, fina lOffset, o utWithPadd ing, | |
986 | 0, f inalBufLen ); | |
987 | ||
988 | if (padd ing != nul l) { | |
989 | int padStart = padding.u npad(outWi thPadding, 0, outLen ); | |
990 | if ( padStart < 0) { | |
991 | throw new BadPadding Exception( "Given fin al block n ot " | |
992 | + "properl y padded") ; | |
993 | } | |
994 | outL en = padSt art; | |
995 | } | |
996 | ||
997 | if (outp utCapacity < outLen) { | |
998 | // r estore so users can retry with a larger buffer | |
999 | ciph er.restore (); | |
1000 | thro w new Shor tBufferExc eption("Ou tput buffe r too shor t: " | |
1001 | + ( outputCapa city) | |
1002 | + " bytes giv en, " + ou tLen | |
1003 | + " bytes nee ded"); | |
1004 | } | |
1005 | // copy the result into user -supplied output buf fer | |
1006 | System.a rraycopy(o utWithPadd ing, 0, ou tput, outp utOffset, outLen); | |
1007 | } else { // encrypting | |
1008 | try { | |
1009 | outL en = final NoPadding( finalBuf, finalOffse t, output, | |
1010 | outputOffs et, finalB ufLen); | |
1011 | } finall y { | |
1012 | // r eset after doFinal() for GCM e ncryption | |
1013 | requ ireReinit = (cipherM ode == GCM _MODE); | |
1014 | } | |
1015 | } | |
1016 | ||
1017 | bu ffered = 0 ; | |
1018 | di ffBlocksiz e = blockS ize; | |
1019 | if (cipherMo de != ECB_ MODE) { | |
1020 | cipher.r eset(); | |
1021 | } | |
1022 | re turn outLe n; | |
1023 | } | |
1024 | ||
1025 | privat e int fina lNoPadding (byte[] in , int inOf s, byte[] out, int o utOfs, | |
1026 | int len) | |
1027 | th rows Illeg alBlockSiz eException , AEADBadT agExceptio n, | |
1028 | Sh ortBufferE xception { | |
1029 | ||
1030 | if ((cipherM ode != GCM _MODE) && (in == nul l || len = = 0)) { | |
1031 | return 0 ; | |
1032 | } | |
1033 | if ((cipherM ode != CFB _MODE) && (cipherMod e != OFB_M ODE) && | |
1034 | (cipherM ode != GCM _MODE) && | |
1035 | ((len % unitBytes) != 0) && (cipherMod e != CTS_M ODE)) { | |
1036 | if ( padding != null) { | |
1037 | throw new IllegalBlo ckSizeExce ption | |
1038 | ("Inpu t length ( with paddi ng) not mu ltiple of " + | |
1039 | unitB ytes + " b ytes"); | |
1040 | } el se { | |
1041 | throw new IllegalBlo ckSizeExce ption | |
1042 | ("Inpu t length n ot multipl e of " + u nitBytes | |
1043 | + " b ytes"); | |
1044 | } | |
1045 | } | |
1046 | in t outLen = 0; | |
1047 | if (decrypti ng) { | |
1048 | outLen = cipher.de cryptFinal (in, inOfs , len, out , outOfs); | |
1049 | } else { | |
1050 | outLen = cipher.en cryptFinal (in, inOfs , len, out , outOfs); | |
1051 | } | |
1052 | re turn outLe n; | |
1053 | } | |
1054 | ||
1055 | // Not e: Wrap() and Unwrap () are the same in | |
1056 | // eac h of SunJC E CipherSp i implemen tation cla sses. | |
1057 | // The y are dupl icated due to export control r equirement s: | |
1058 | // All CipherSpi implement ation must be final. | |
1059 | /** | |
1060 | * Wra p a key. | |
1061 | * | |
1062 | * @pa ram key th e key to b e wrapped. | |
1063 | * | |
1064 | * @re turn the w rapped key . | |
1065 | * | |
1066 | * @ex ception Il legalBlock SizeExcept ion if thi s cipher i s a block | |
1067 | * cip her, no pa dding has been reque sted, and the length of the | |
1068 | * enc oding of t he key to be wrapped is not a | |
1069 | * mul tiple of t he block s ize. | |
1070 | * | |
1071 | * @ex ception In validKeyEx ception if it is imp ossible or unsafe to | |
1072 | * wra p the key with this cipher (e. g., a hard ware prote cted key i s | |
1073 | * bei ng passed to a softw are only c ipher). | |
1074 | */ | |
1075 | byte[] wrap(Key key) | |
1076 | th rows Illeg alBlockSiz eException , InvalidK eyExceptio n { | |
1077 | by te[] resul t = null; | |
1078 | ||
1079 | tr y { | |
1080 | byte[] e ncodedKey = key.getE ncoded(); | |
1081 | if ((enc odedKey == null) || (encodedKe y.length = = 0)) { | |
1082 | thro w new Inva lidKeyExce ption("Can not get an encoding of " + | |
1083 | "the key to be wrapped") ; | |
1084 | } | |
1085 | result = doFinal(e ncodedKey, 0, encode dKey.lengt h); | |
1086 | } catch (Bad PaddingExc eption e) { | |
1087 | // Shoul d never ha ppen | |
1088 | } | |
1089 | re turn resul t; | |
1090 | } | |
1091 | ||
1092 | /** | |
1093 | * Unw rap a prev iously wra pped key. | |
1094 | * | |
1095 | * @pa ram wrappe dKey the k ey to be u nwrapped. | |
1096 | * | |
1097 | * @pa ram wrappe dKeyAlgori thm the al gorithm th e wrapped key is for . | |
1098 | * | |
1099 | * @pa ram wrappe dKeyType t he type of the wrapp ed key. | |
1100 | * Thi s is one o f <code>Ci pher.SECRE T_KEY</cod e>, | |
1101 | * <co de>Cipher. PRIVATE_KE Y</code>, or <code>C ipher.PUBL IC_KEY</co de>. | |
1102 | * | |
1103 | * @re turn the u nwrapped k ey. | |
1104 | * | |
1105 | * @ex ception No SuchAlgori thmExcepti on if no i nstalled p roviders | |
1106 | * can create ke ys of type <code>wra ppedKeyTyp e</code> f or the | |
1107 | * <co de>wrapped KeyAlgorit hm</code>. | |
1108 | * | |
1109 | * @ex ception In validKeyEx ception if <code>wra ppedKey</c ode> does not | |
1110 | * rep resent a w rapped key of type < code>wrapp edKeyType< /code> for | |
1111 | * the <code>wra ppedKeyAlg orithm</co de>. | |
1112 | */ | |
1113 | Key un wrap(byte[ ] wrappedK ey, String wrappedKe yAlgorithm , | |
1114 | int w rappedKeyT ype) | |
1115 | th rows Inval idKeyExcep tion, NoSu chAlgorith mException { | |
1116 | by te[] encod edKey; | |
1117 | tr y { | |
1118 | encodedK ey = doFin al(wrapped Key, 0, wr appedKey.l ength); | |
1119 | } catch (Bad PaddingExc eption ePa dding) { | |
1120 | throw ne w InvalidK eyExceptio n("The wra pped key i s not padd ed " + | |
1121 | "correct ly"); | |
1122 | } catch (Ill egalBlockS izeExcepti on eBlockS ize) { | |
1123 | throw ne w InvalidK eyExceptio n("The wra pped key d oes not ha ve " + | |
1124 | "the cor rect lengt h"); | |
1125 | } | |
1126 | re turn Const ructKeys.c onstructKe y(encodedK ey, wrappe dKeyAlgori thm, | |
1127 | wrappedK eyType); | |
1128 | } | |
1129 | ||
1130 | /** | |
1131 | * Con tinues a m ulti-part update of the Additi onal Authe ntication | |
1132 | * Dat a (AAD), u sing a sub set of the provided buffer. | |
1133 | * <p> | |
1134 | * Cal ls to this method pr ovide AAD to the cip her when o perating i n | |
1135 | * mod es such as AEAD (GCM /CCM). If this ciph er is oper ating in | |
1136 | * eit her GCM or CCM mode, all AAD m ust be sup plied befo re beginni ng | |
1137 | * ope rations on the ciphe rtext (via the {@cod e update} and {@code | |
1138 | * doF inal} meth ods). | |
1139 | * | |
1140 | * @pa ram src th e buffer c ontaining the AAD | |
1141 | * @pa ram offset the offse t in {@cod e src} whe re the AAD input sta rts | |
1142 | * @pa ram len th e number o f AAD byte s | |
1143 | * | |
1144 | * @th rows Illeg alStateExc eption if this ciphe r is in a wrong stat e | |
1145 | * (e. g., has no t been ini tialized), does not accept AAD , or if | |
1146 | * ope rating in either GCM or CCM mo de and one of the {@ code updat e} | |
1147 | * met hods has a lready bee n called f or the act ive | |
1148 | * enc ryption/de cryption o peration | |
1149 | * @th rows Unsup portedOper ationExcep tion if th is method | |
1150 | * has not been overridden by an imp lementatio n | |
1151 | * | |
1152 | * @si nce 1.8 | |
1153 | */ | |
1154 | void u pdateAAD(b yte[] src, int offse t, int len ) { | |
1155 | if (requireR einit) { | |
1156 | throw ne w IllegalS tateExcept ion | |
1157 | ("Mu st use eit her differ ent key or iv for GC M encrypti on"); | |
1158 | } | |
1159 | ci pher.updat eAAD(src, offset, le n); | |
1160 | } | |
1161 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.