View Javadoc
1   /*
2    * GordianKnot: Security Suite
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.gordianknot.api.cipher;
18  
19  import io.github.tonywasher.joceanus.gordianknot.api.base.GordianException;
20  
21  import java.util.Arrays;
22  
23  /**
24   * GordianKnot base for Cipher.
25   */
26  public interface GordianCipher {
27      /**
28       * Determine the maximum number of output bytes that will be produced for the given number of
29       * input bytes.
30       *
31       * @param pLength the number of input bytes
32       * @return # of output bytes
33       */
34      int getOutputLength(int pLength);
35  
36      /**
37       * Process the passed data and return intermediate results.
38       *
39       * @param pBytes Bytes to update cipher with
40       * @return the intermediate processed data
41       * @throws GordianException on error
42       */
43      default byte[] update(final byte[] pBytes) throws GordianException {
44          return update(pBytes, 0, pBytes == null ? 0 : pBytes.length);
45      }
46  
47      /**
48       * Process the passed data and return intermediate results.
49       *
50       * @param pBytes  Bytes to update cipher with
51       * @param pOffset offset within pBytes to read bytes from
52       * @param pLength length of data to update with
53       * @return the intermediate processed data
54       * @throws GordianException on error
55       */
56      default byte[] update(final byte[] pBytes,
57                            final int pOffset,
58                            final int pLength) throws GordianException {
59          /* Create output buffer */
60          final int myLen = getOutputLength(pLength);
61          final byte[] myOutput = new byte[myLen];
62  
63          /* Process the data */
64          final int myOut = update(pBytes, pOffset, pLength, myOutput, 0);
65  
66          /* Return full buffer if possible */
67          if (myOut == myLen) {
68              return myOutput;
69          }
70  
71          /* Cut down buffer */
72          final byte[] myReturn = Arrays.copyOf(myOutput, myOut);
73          Arrays.fill(myOutput, (byte) 0);
74          return myReturn;
75      }
76  
77      /**
78       * Process the passed data and return intermediate results.
79       *
80       * @param pBytes  Bytes to update cipher with
81       * @param pOffset offset within pBytes to read bytes from
82       * @param pLength length of data to update with
83       * @param pOutput the output buffer to receive processed data
84       * @return the number of bytes transferred to the output buffer
85       * @throws GordianException on error
86       */
87      default int update(final byte[] pBytes,
88                         final int pOffset,
89                         final int pLength,
90                         final byte[] pOutput) throws GordianException {
91          return update(pBytes, pOffset, pLength, pOutput, 0);
92      }
93  
94      /**
95       * Process the passed data and return intermediate results.
96       *
97       * @param pBytes     Bytes to update cipher with
98       * @param pOffset    offset within pBytes to read bytes from
99       * @param pLength    length of data to update with
100      * @param pOutput    the output buffer to receive processed data
101      * @param pOutOffset offset within pOutput to write bytes to
102      * @return the number of bytes transferred to the output buffer
103      * @throws GordianException on error
104      */
105     int update(byte[] pBytes,
106                int pOffset,
107                int pLength,
108                byte[] pOutput,
109                int pOutOffset) throws GordianException;
110 
111     /**
112      * Complete the Cipher operation and return final results.
113      *
114      * @return the remaining processed data
115      * @throws GordianException on error
116      */
117     default byte[] finish() throws GordianException {
118         /* Create output buffer */
119         final int myLen = getOutputLength(0);
120         final byte[] myOutput = new byte[myLen];
121 
122         /* Process the data */
123         final int myOut = finish(myOutput, 0);
124 
125         /* Return full buffer if possible */
126         if (myOut == myLen) {
127             return myOutput;
128         }
129 
130         /* Cut down buffer */
131         final byte[] myReturn = Arrays.copyOf(myOutput, myOut);
132         Arrays.fill(myOutput, (byte) 0);
133         return myReturn;
134     }
135 
136     /**
137      * Process the passed data and return final results.
138      *
139      * @param pBytes Bytes to update cipher with
140      * @return the remaining processed data
141      * @throws GordianException on error
142      */
143     default byte[] finish(final byte[] pBytes) throws GordianException {
144         return finish(pBytes, 0, pBytes == null ? 0 : pBytes.length);
145     }
146 
147     /**
148      * Process the passed data and return final results.
149      *
150      * @param pBytes  Bytes to update cipher with
151      * @param pOffset offset within pBytes to read bytes from
152      * @param pLength length of data to update with
153      * @return the remaining processed data
154      * @throws GordianException on error
155      */
156     default byte[] finish(final byte[] pBytes,
157                           final int pOffset,
158                           final int pLength) throws GordianException {
159         /* Create output buffer */
160         final int myLen = getOutputLength(pLength);
161         final byte[] myOutput = new byte[myLen];
162 
163         /* Process the data */
164         final int myOut = finish(pBytes, pOffset, pLength, myOutput, 0);
165 
166         /* Return full buffer if possible */
167         if (myOut == myLen) {
168             return myOutput;
169         }
170 
171         /* Cut down buffer */
172         final byte[] myReturn = Arrays.copyOf(myOutput, myOut);
173         Arrays.fill(myOutput, (byte) 0);
174         return myReturn;
175     }
176 
177     /**
178      * Process the passed data and return final results.
179      *
180      * @param pBytes  Bytes to update cipher with
181      * @param pOffset offset within pBytes to read bytes from
182      * @param pLength length of data to update with
183      * @param pOutput the output buffer to receive processed data
184      * @return the number of bytes transferred to the output buffer
185      * @throws GordianException on error
186      */
187     default int finish(final byte[] pBytes,
188                        final int pOffset,
189                        final int pLength,
190                        final byte[] pOutput) throws GordianException {
191         return finish(pBytes, pOffset, pLength, pOutput, 0);
192     }
193 
194     /**
195      * Process the passed data and return final results.
196      *
197      * @param pBytes     Bytes to update cipher with
198      * @param pOffset    offset within pBytes to read bytes from
199      * @param pLength    length of data to update with
200      * @param pOutput    the output buffer to receive processed data
201      * @param pOutOffset offset within pOutput to write bytes to
202      * @return the number of bytes transferred to the output buffer
203      * @throws GordianException on error
204      */
205     default int finish(final byte[] pBytes,
206                        final int pOffset,
207                        final int pLength,
208                        final byte[] pOutput,
209                        final int pOutOffset) throws GordianException {
210         /* Update the data */
211         final int myLen = update(pBytes, pOffset, pLength, pOutput, pOutOffset);
212 
213         /* Complete the operation */
214         return myLen + finish(pOutput, pOutOffset + myLen);
215     }
216 
217     /**
218      * Complete the Cipher operation and return final results.
219      *
220      * @param pOutput    the output buffer to receive processed data
221      * @param pOutOffset offset within pOutput to write bytes to
222      * @return the number of bytes transferred to the output buffer
223      * @throws GordianException on error
224      */
225     int finish(byte[] pOutput,
226                int pOutOffset) throws GordianException;
227 }