native.jniutil.jni_asserts.h Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcprov-lts8on Show documentation
Show all versions of bcprov-lts8on Show documentation
The Long Term Stable (LTS) Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains the JCA/JCE provider and low-level API for the BC LTS version 2.73.7 for Java 8 and later.
//
//
#ifndef BC_FIPS_JNI_ASSERTS_H
#define BC_FIPS_JNI_ASSERTS_H
#include "bytearraycritical.h"
#include "longarraycritical.h"
#include "bytearrays.h"
#include "exceptions.h"
static inline bool check_range(size_t size, size_t offset, size_t len) {
return (len <= size) && (offset <= size - len);
}
static inline bool critical_long_not_null(critical_longarray_ctx *in, const char *failMsg, JNIEnv *env) {
if (in == NULL || in->array == NULL) {
throw_java_NPE(env, failMsg);
return false;
}
return true;
}
static inline bool critical_not_null(critical_bytearray_ctx *in, const char *failMsg, JNIEnv *env) {
if (in == NULL || in->array == NULL) {
throw_java_NPE(env, failMsg);
return false;
}
return true;
}
static inline bool bytearray_not_null(java_bytearray_ctx *in, const char *failMsg, JNIEnv *env) {
if (in == NULL || in->array == NULL) {
throw_java_NPE(env, failMsg);
return false;
}
return true;
}
/**
* This is a collection of tests for input and output arrays along with their offsets and an overall length.,
* @param in input critical array
* @param input_offset input offset
* @param len total bytes to be processed
* @param output the output array
* @param output_offset the output offset
* @param env the java env
* @return true if successful, throws java exception and returns false if not successful.
*/
static inline bool input_and_output_critical_are_in_range_for_offsets_and_len(
critical_bytearray_ctx *in,
const int input_offset,
const int len,
critical_bytearray_ctx *output,
int output_offset, JNIEnv *env) {
if (input_offset < 0) {
throw_bc_data_length_exception(env, "input offset was negative");
return false;
}
if (output_offset < 0) {
throw_bc_output_length_exception(env, "output offset was negative");
return false;
}
if (len < 0) {
throw_bc_data_length_exception(env, "len was negative");
return false;
}
if (!check_range(in->size, (size_t) input_offset, (size_t) len)) {
throw_bc_data_length_exception(env,
"input buffer too short");
return false;
}
if (!check_range(output->size, (size_t) output_offset, (size_t) len)) {
throw_bc_output_length_exception(env,
"output buffer too short");
return false;
}
return true;
}
static inline bool process_critical_blocks_valid(
critical_bytearray_ctx *in,
const int in_offset,
const int blockCount,
critical_bytearray_ctx *out,
int out_offset,
JNIEnv *env,
const int blockSize) {
if (in_offset < 0) {
throw_bc_data_length_exception(env,
"input offset is negative");
return false;
}
if (out_offset < 0) {
throw_bc_output_length_exception(env,
"output offset is negative");
return false;
}
if (blockCount < 0) {
throw_bc_data_length_exception(env,
"blockCount is negative");
return false;
}
size_t extent = (size_t) blockSize * (size_t) blockCount;
if (!check_range(in->size, (size_t) in_offset, extent)) {
throw_bc_data_length_exception(env,
"input buffer too short");
return false;
}
if (!check_range(out->size, (size_t) out_offset, extent)) {
throw_bc_output_length_exception(env,
"output buffer too short");
return false;
}
return true;
}
/**
* Check and iv is not null and 16 bytes long, throws java exceptions if not met.
* @param env the java environment.
* @param iv the array containing the iv.
* @return
*/
static inline bool ivlen_is_16_and_not_null(JNIEnv *env, java_bytearray_ctx *iv) {
if (iv->array == NULL) {
throw_java_NPE(env, "iv is null");
return false;
}
if (iv->size == 16) {
return true;
}
throw_java_illegal_argument(env, "iv must be only 16 bytes");
return false;
}
/**
* Check and iv is not null and 16 bytes long, throws java exceptions if not met.
* @param env the java environment.
* @param iv the array containing the iv.
* @param len the length of the IV
* @return
*/
static inline bool ivlen_is_16_and_not_null_with_len(JNIEnv *env, java_bytearray_ctx *iv, int32_t ivLen) {
if (iv->array == NULL) {
throw_java_NPE(env, "iv is null");
return false;
}
// Assert fundamental size
if (ivLen != 16) {
throw_java_illegal_argument(env, "iv must be only 16 bytes");
return false;
}
// Check array can accommodate ivLen
if (iv->size < ivLen) {
throw_java_illegal_argument(env, "iv array length is less than ivLen");
return false;
}
return true;
}
/**
* Assert aes key sizes, throws java exceptions if not.
* @param env java env var
* @param key the key
* @return true if ok
*/
static inline bool aes_keysize_is_valid_and_not_null_with_len(JNIEnv *env, java_bytearray_ctx *key, int32_t keyLen) {
if (key->array == NULL) {
throw_java_NPE(env, "key was null");
return false;
}
// basic assertion for size, asserts non-negative
if (keyLen < 16) {
throw_java_illegal_argument(env, "key must be only 16, 24 or 32 bytes long");
return false;
}
// Can array accommodate key
if (key->size < keyLen) {
throw_java_illegal_argument(env, "key array is less than keyLen");
return false;
}
switch (keyLen) {
case 16:
case 24:
case 32:
return true;
default:
throw_java_illegal_argument(env, "key must be only 16, 24 or 32 bytes long");
}
return false;
}
/**
* Assert aes key sizes, throws java exceptions if not.
* @param env java env var
* @param key the key
* @return true if ok
*/
static inline bool aes_keysize_is_valid_and_not_null_with_len_not_24(JNIEnv *env, java_bytearray_ctx *key, int32_t keyLen) {
if (key->array == NULL) {
throw_java_NPE(env, "key was null");
return false;
}
// basic assertion for size, asserts non-negative
if (keyLen < 16) {
throw_java_illegal_argument(env, "key must be only 16, or 32 bytes long");
return false;
}
// Can array accommodate key
if (key->size < keyLen) {
throw_java_illegal_argument(env, "key array is less than keyLen");
return false;
}
switch (keyLen) {
case 16:
case 32:
return true;
default:
throw_java_illegal_argument(env, "key must be only 16, or 32 bytes long");
}
return false;
}
/**
* Assert aes key sizes, throws java exceptions if not.
* @param env java env var
* @param key the key
* @return true if ok
*/
static inline bool aes_keysize_is_valid_and_not_null(JNIEnv *env, java_bytearray_ctx *key) {
if (key->array == NULL) {
throw_java_NPE(env, "key was null");
return false;
}
switch (key->size) {
case 16:
case 24:
case 32:
return true;
default:
throw_java_illegal_argument(env, "key must be only 16, 24 or 32 bytes long");
}
return false;
}
/**
* Assert aes key sizes, throws java exceptions if not.
* @param env java env var
* @param key the key
* @return true if ok
*/
static inline bool aes_keysize_is_valid_and_not_null_not_24(JNIEnv *env, java_bytearray_ctx *key) {
if (key->array == NULL) {
throw_java_NPE(env, "key was null");
return false;
}
switch (key->size) {
case 16:
case 32:
return true;
default:
throw_java_illegal_argument(env, "key must be only 16, or 32 bytes long");
}
return false;
}
/**
* Asserts key sizes but also accepts null keys.
* This is used in cases where a null key is supplied because the implementation
* is expected to use an old key but with a new iv.
* @param env
* @param key
* @return
*/
static inline bool aes_keysize_is_valid_or_null(JNIEnv *env, java_bytearray_ctx *key) {
if (key->array == NULL) {
return true;
}
switch (key->size) {
case 16:
case 24:
case 32:
return true;
default:
throw_java_illegal_argument(env, "key must be only 16, 24 or 32 bytes long");
}
return false;
}
/**
* Asserts that for a single critical byte array that it is not null and the offset + len are within the bounds
* of the critical array.
* @param array the array to test
* @param offset input offset
* @param len length
* @param env java env
* @param beforeThrow
* @return true if valid
*/
static inline bool
critical_offset_and_len_are_in_range(critical_bytearray_ctx *array, int offset, int len, JNIEnv *env) {
if (offset < 0) {
throw_java_illegal_argument(env, "offset is negative");
return false;
}
if (len < 0) {
throw_java_illegal_argument(env,
"len is negative");
return false;
}
if (!check_range(array->size, (size_t) offset, (size_t) len)) {
throw_java_illegal_argument(env,
"array too short for offset + len");
return false;
}
return true;
}
/**
* Asserts that for a single critical byte array that it is not null and the offset + len are within the bounds
* of the critical array.
* @param array the array to test
* @param offset input offset
* @param len length
* @param env java env
* @param beforeThrow
* @return true if valid
*/
static inline bool
critical_offset_and_len_are_in_range_with_messages(
critical_bytearray_ctx *array,
int offset,
int len,
JNIEnv *env,
const char *arrayNUll,
const char *offsetNeg,
const char *lenNeg,
const char *tooShort) {
if (array->array == NULL) {
throw_java_illegal_argument(env, arrayNUll);
return false;
}
if (offset < 0) {
throw_java_illegal_argument(env, offsetNeg);
return false;
}
if (len < 0) {
throw_java_illegal_argument(env,
lenNeg);
return false;
}
if (!check_range(array->size, (size_t) offset, (size_t) len)) {
throw_java_illegal_argument(env,
tooShort);
return false;
}
return true;
}
/**
* Asserts that for a single critical byte array that it is not null and the offset + len are within the bounds
* of the critical array.
* @param array the array to test
* @param offset input offset
* @param len length
* @param env java env
* @param beforeThrow
* @return true if valid
*/
static inline bool
critical_long_offset_and_len_are_in_range(critical_longarray_ctx *array, int offset, int len, JNIEnv *env) {
if (offset < 0) {
throw_java_illegal_argument(env, "offset is negative");
return false;
}
if (len < 0) {
throw_java_illegal_argument(env,
"len is negative");
return false;
}
if (!check_range(array->size, (size_t) offset, (size_t) len)) {
throw_java_illegal_argument(env,
"array too short for offset + len");
return false;
}
return true;
}
/**
* Assert single array, inOff >=0, len >=0, inOff+len <= array len for non critical byte array.
*
* This method does not assert java byte array is Null, if null all comparisons will be done on
* as if it is a zero length array which may mislead callers,
* java byte array is null assertion should be done before calling this.
*
* @param array the array to test
* @param inOff the input offset
* @param len the length
* @param env the java env
* @return true if ok
*/
static inline bool bytearray_offset_and_len_are_in_range(java_bytearray_ctx *array, int inOff, int len, JNIEnv *env) {
if (inOff < 0) {
throw_java_illegal_argument(env, "offset is negative");
return false;
}
if (len < 0) {
throw_java_illegal_argument(env, "len is negative");
return false;
}
if (!check_range(array->size, (size_t) inOff, (size_t) len)) {
throw_java_illegal_argument(env,
"array too short for offset + len");
return false;
}
return true;
}
/**
* Assert single array not null and
* assert inOff >=0, len >=0, inOff+len <= array len for non critical byte array.
*
*
* @param array the array to test
* @param inOff the input offset
* @param len the length
* @param env the java env
* @param
* @return true if ok
*/
static inline bool bytearray_offset_and_len_are_in_range_not_null_msgs(
java_bytearray_ctx *array,
int inOff,
int len,
JNIEnv *env,
const char *nonceNullMsg,
const char *offsetNegMsg,
const char *lenNegMessage,
const char *arrayTooShortMsg) {
if (array->array == NULL) {
throw_java_NPE(env, nonceNullMsg);
return false;
}
if (inOff < 0) {
throw_java_illegal_argument(env, offsetNegMsg);
return false;
}
if (len < 0) {
throw_java_illegal_argument(env, lenNegMessage);
return false;
}
if (!check_range(array->size, (size_t) inOff, (size_t) len)) {
throw_java_illegal_argument(env,
arrayTooShortMsg);
return false;
}
return true;
}
/**
* Assert single array offset for critical byte array.
*
* This method does not assert java byte array is Null, if null all comparisons will be done on
* as if it is a zero length array which may mislead callers,
* java byte array is null assertion should be done before calling this.
*
* @param array the array to test
* @param offset the input offset
* @param len the length
* @param env the java env
* @return true if ok
*/
static inline bool critical_offset_is_in_range(critical_bytearray_ctx *array, int offset, JNIEnv *env) {
if (offset < 0) {
throw_java_illegal_argument(env,
"offset is negative");
return false;
}
if (offset > array->size) {
throw_java_illegal_argument(env, "offset past end of array");
return false;
}
return true;
}
/**
* Assert single array offset for critical long array.
*
* This method does not assert java byte array is Null, if null all comparisons will be done on
* as if it is a zero length array which may mislead callers,
* java byte array is null assertion should be done before calling this.
*
* @param array the array to test
* @param offset the input offset
* @param len the length
* @param env the java env
* @return true if ok
*/
static inline bool critical_long_offset_is_in_range(critical_longarray_ctx *array, int offset, JNIEnv *env) {
if (offset < 0) {
throw_java_illegal_argument(env,
"offset is negative");
return false;
}
if (offset > array->size) {
throw_java_illegal_argument(env, "offset past end of array");
return false;
}
return true;
}
/**
* Assert single array offset for non critical byte array.
*
* This method does not assert java byte array is Null, if null all comparisons will be done on
* as if it is a zero length array which may mislead callers,
* java byte array is null assertion should be done before calling this.
*
* @param array the array to test
* @param inOff the input offset
* @param env the java env
* @return true if ok
*/
static inline bool bytearray_offset_is_in_range(java_bytearray_ctx *array, int inOff, JNIEnv *env) {
if (inOff < 0) {
throw_java_illegal_argument(env, "offset is negative");
return false;
}
if (inOff > array->size) {
throw_java_illegal_argument(env, "offset past end of array");
return false;
}
return true;
}
/**
* Performs the process block input validation.
* Returns false if there is an issue while throwing and exception.
* @param env
* @param input
* @param output
* @param inArray
* @param inOffset
* @param outArray
* @param outOffset
* @param blocks
* @param blockSize
* @param inStart pass by reference
* @param outStart pass by reference
* @return
*/
static inline bool block_processing_init(
JNIEnv *env,
critical_bytearray_ctx *input,
critical_bytearray_ctx *output,
jbyteArray inArray,
jint inOffset,
jbyteArray outArray,
jint outOffset,
int blocks,
int blockSize,
void **inStart, void **outStart) {
//
// Wrap but only grab lengths until we need the data.
//
init_critical_ctx(output, env, outArray);
init_critical_ctx(input, env, inArray);
if (!critical_not_null(output, "output was null", env)) {
return false;
}
if (!critical_not_null(input, "input was null", env)) {
return false;
}
if (!process_critical_blocks_valid(input, inOffset, blocks,
output, outOffset, env, blockSize)) {
return false;
}
//
// out first
//
if (!load_critical_ctx(output)) {
throw_java_invalid_state(env, "unable to obtain ptr to valid output array");
return false;
}
if (!load_critical_ctx(input)) {
release_critical_ctx(output);
throw_java_invalid_state(env, "unable to obtain ptr to valid input array");
return false;
}
*inStart = input->critical + inOffset;
*outStart = output->critical + outOffset;
return true;
}
/**
* Performs the process block input validation.
* Returns false if there is an issue while throwing an exception.
* @param env
* @param input
* @param output
* @param inArray
* @param input_offset
* @param outArray
* @param output_offset
* @param blocks
* @param blockSize
* @param inStart pass by reference
* @param outStart pass by reference
* @return
*/
static inline bool byte_processing_init(
JNIEnv *env,
critical_bytearray_ctx *input,
critical_bytearray_ctx *output,
jbyteArray inArray,
jint input_offset,
jbyteArray outArray,
jint output_offset,
int length,
void **inStart, void **outStart) {
//
// Wrap but only extract java byte array lengths.
// Critical access to data is requested after null, offsets and length are
// verified against the lengths of the input and output arrays.
//
init_critical_ctx(output, env, outArray);
init_critical_ctx(input, env, inArray);
if (!critical_not_null(output, "output was null", env)) {
return false;
}
if (!critical_not_null(input, "input was null", env)) {
return false;
}
if (!input_and_output_critical_are_in_range_for_offsets_and_len(
input,
input_offset,
length,
output,
output_offset,
env)) {
return false;
}
//
// Here we request the JVM give us pointers to the array data within the JVM.
// If the JVM is unable to do that we return false.
// Given we have asserted length and null by this point the assumption is that the
// JVM may be in an adverse state if it cannot supply a pointer to an otherwise valid byte array.
//
//
// Callers to byte_processing_init are responsible for releasing the pointers back to the jvm after
// they have finished accessing the data.
//
if (!load_critical_ctx(output)) {
throw_java_invalid_state(env, "unable to obtain ptr to valid output array");
return false;
}
if (!load_critical_ctx(input)) {
release_critical_ctx(output);
throw_java_invalid_state(env, "unable to obtain ptr to valid input array");
return false;
}
//
// By this point input_offset and output_offset have been tested as not negative and the
// byte arrays on the java side are not null and long enough to contain the length.
//
*inStart = input->critical + input_offset;
*outStart = output->critical + output_offset;
return true;
}
#endif //BC_FIPS_JNI_ASSERTS_H
© 2015 - 2024 Weber Informatics LLC | Privacy Policy