TEE_Result tee_cipher_get_block_size(uint32_t algo, size_t *size) { TEE_Result res; int ltc_cipherindex; res = tee_algo_to_ltc_cipherindex(algo, <c_cipherindex); if (res != TEE_SUCCESS) return TEE_ERROR_NOT_SUPPORTED; *size = cipher_descriptor[ltc_cipherindex].block_length; return TEE_SUCCESS; }
TEE_Result tee_authenc_init( void *ctx, uint32_t algo, TEE_OperationMode mode, const uint8_t *key, size_t key_len, const uint8_t *nonce, size_t nonce_len, size_t tag_len, size_t aad_len, size_t payload_len) { TEE_Result res; int ltc_res; int ltc_cipherindex; unsigned char *payload, *res_payload; struct tee_ccm_state *ccm; struct tee_gcm_state *gcm; res = tee_algo_to_ltc_cipherindex(algo, <c_cipherindex); if (res != TEE_SUCCESS) return TEE_ERROR_NOT_SUPPORTED; switch (algo) { case TEE_ALG_AES_CCM: /* Check the key length */ if ((!key) || (key_len > TEE_CCM_KEY_MAX_LENGTH)) return TEE_ERROR_BAD_PARAMETERS; /* check the nonce */ if (nonce_len > TEE_CCM_NONCE_MAX_LENGTH) return TEE_ERROR_BAD_PARAMETERS; /* check the tag len */ if ((tag_len < 4) || (tag_len > TEE_CCM_TAG_MAX_LENGTH) || (tag_len % 2 != 0)) return TEE_ERROR_NOT_SUPPORTED; /* allocate payload */ payload = malloc(payload_len + TEE_CCM_KEY_MAX_LENGTH); if (!payload) return TEE_ERROR_OUT_OF_MEMORY; res_payload = malloc(payload_len + TEE_CCM_KEY_MAX_LENGTH); if (!res_payload) { free(payload); return TEE_ERROR_OUT_OF_MEMORY; } /* initialize the structure */ ccm = ctx; memset(ccm, 0, sizeof(struct tee_ccm_state)); memcpy(ccm->key, key, key_len); ccm->key_len = key_len; /* the key length */ if (nonce && nonce_len) { memcpy(ccm->nonce, nonce, nonce_len); ccm->nonce_len = nonce_len; } else { ccm->nonce_len = 0; } ccm->tag_len = tag_len; ccm->aad_len = aad_len; ccm->payload_len = payload_len; ccm->payload = payload; ccm->res_payload = res_payload; ccm->ltc_cipherindex = ltc_cipherindex; if (ccm->aad_len) { ccm->header = malloc(ccm->aad_len); if (!ccm->header) { free(payload); free(res_payload); return TEE_ERROR_OUT_OF_MEMORY; } } /* memset the payload to 0 that will be used for padding */ memset(ccm->payload, 0, payload_len + TEE_CCM_KEY_MAX_LENGTH); break; case TEE_ALG_AES_GCM: /* reset the state */ gcm = ctx; memset(gcm, 0, sizeof(struct tee_gcm_state)); gcm->tag_len = tag_len; ltc_res = gcm_init( &gcm->ctx, ltc_cipherindex, key, key_len); if (ltc_res != CRYPT_OK) return TEE_ERROR_BAD_STATE; /* Add the IV */ ltc_res = gcm_add_iv(&gcm->ctx, nonce, nonce_len); if (ltc_res != CRYPT_OK) return TEE_ERROR_BAD_STATE; break; default: return TEE_ERROR_NOT_SUPPORTED; } return TEE_SUCCESS; }
TEE_Result tee_cipher_init3(void *ctx, uint32_t algo, TEE_OperationMode mode, const uint8_t *key1, size_t key1_len, const uint8_t *key2, size_t key2_len, const uint8_t *iv, size_t iv_len) { TEE_Result res; int ltc_res, ltc_cipherindex; uint8_t *real_key, key_array[24]; size_t real_key_len; struct symmetric_CTS *cts; res = tee_algo_to_ltc_cipherindex(algo, <c_cipherindex); if (res != TEE_SUCCESS) return TEE_ERROR_NOT_SUPPORTED; switch (algo) { case TEE_ALG_AES_ECB_NOPAD: case TEE_ALG_DES_ECB_NOPAD: ltc_res = ecb_start( ltc_cipherindex, key1, key1_len, 0, (symmetric_ECB *)ctx); break; case TEE_ALG_DES3_ECB_NOPAD: /* either des3 or des2, depending on the size of the key */ get_des2_key(key1, key1_len, key_array, &real_key, &real_key_len); ltc_res = ecb_start( ltc_cipherindex, real_key, real_key_len, 0, (symmetric_ECB *)ctx); break; case TEE_ALG_AES_CBC_NOPAD: case TEE_ALG_DES_CBC_NOPAD: if (iv_len != (size_t)cipher_descriptor[ltc_cipherindex].block_length) return TEE_ERROR_BAD_PARAMETERS; ltc_res = cbc_start( ltc_cipherindex, iv, key1, key1_len, 0, (symmetric_CBC *)ctx); break; case TEE_ALG_DES3_CBC_NOPAD: /* either des3 or des2, depending on the size of the key */ get_des2_key(key1, key1_len, key_array, &real_key, &real_key_len); if (iv_len != (size_t)cipher_descriptor[ltc_cipherindex].block_length) return TEE_ERROR_BAD_PARAMETERS; ltc_res = cbc_start( ltc_cipherindex, iv, real_key, real_key_len, 0, (symmetric_CBC *)ctx); break; case TEE_ALG_AES_CTR: if (iv_len != (size_t)cipher_descriptor[ltc_cipherindex].block_length) return TEE_ERROR_BAD_PARAMETERS; ltc_res = ctr_start( ltc_cipherindex, iv, key1, key1_len, 0, CTR_COUNTER_BIG_ENDIAN, (symmetric_CTR *)ctx); break; case TEE_ALG_AES_CTS: cts = (struct symmetric_CTS *)ctx; res = tee_cipher_init3( (void *)(&(cts->ecb)), TEE_ALG_AES_ECB_NOPAD, mode, key1, key1_len, key2, key2_len, iv, iv_len); if (res != TEE_SUCCESS) return res; res = tee_cipher_init3( (void *)(&(cts->cbc)), TEE_ALG_AES_CBC_NOPAD, mode, key1, key1_len, key2, key2_len, iv, iv_len); if (res != TEE_SUCCESS) return res; ltc_res = CRYPT_OK; break; case TEE_ALG_AES_XTS: if (key1_len != key2_len) return TEE_ERROR_BAD_PARAMETERS; ltc_res = xts_start( ltc_cipherindex, key1, key2, key1_len, 0, (symmetric_xts *)ctx); break; default: return TEE_ERROR_NOT_SUPPORTED; } if (ltc_res == CRYPT_OK) return TEE_SUCCESS; else return TEE_ERROR_BAD_STATE; }