82. EPMO Open Source Coordination Office Redaction File Detail Report

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.

82.1 Files compared

# 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

82.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 2320
Changed 1 2
Inserted 0 0
Removed 0 0

82.3 Comparison options

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

82.4 Active regular expressions

No regular expressions were active.

82.5 Comparison detail

  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   }