int crypto4xx_setkey_aes_ccm(struct crypto_aead *cipher, const u8 *key, unsigned int keylen) { struct crypto_tfm *tfm = crypto_aead_tfm(cipher); struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); struct dynamic_sa_ctl *sa; int rc = 0; rc = crypto4xx_setup_fallback(ctx, cipher, key, keylen); if (rc) return rc; if (ctx->sa_in || ctx->sa_out) crypto4xx_free_sa(ctx); rc = crypto4xx_alloc_sa(ctx, SA_AES128_CCM_LEN + (keylen - 16) / 4); if (rc) return rc; /* Setup SA */ sa = (struct dynamic_sa_ctl *) ctx->sa_in; sa->sa_contents.w = SA_AES_CCM_CONTENTS | (keylen << 2); set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV, SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE, SA_NO_HEADER_PROC, SA_HASH_ALG_CBC_MAC, SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC, SA_OPCODE_HASH_DECRYPT, DIR_INBOUND); set_dynamic_sa_command_1(sa, CRYPTO_MODE_CTR, SA_HASH_MODE_HASH, CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF, SA_SEQ_MASK_OFF, SA_MC_ENABLE, SA_NOT_COPY_PAD, SA_COPY_PAYLOAD, SA_NOT_COPY_HDR); sa->sa_command_1.bf.key_len = keylen >> 3; crypto4xx_memcpy_to_le32(get_dynamic_sa_key_field(sa), key, keylen); memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4); sa = (struct dynamic_sa_ctl *) ctx->sa_out; set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV, SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE, SA_NO_HEADER_PROC, SA_HASH_ALG_CBC_MAC, SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC, SA_OPCODE_ENCRYPT_HASH, DIR_OUTBOUND); set_dynamic_sa_command_1(sa, CRYPTO_MODE_CTR, SA_HASH_MODE_HASH, CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF, SA_SEQ_MASK_OFF, SA_MC_ENABLE, SA_COPY_PAD, SA_COPY_PAYLOAD, SA_NOT_COPY_HDR); sa->sa_command_1.bf.key_len = keylen >> 3; return 0; }
/** * HASH SHA1 Functions */ static int crypto4xx_hash_alg_init(struct crypto_tfm *tfm, unsigned int sa_len, unsigned char ha, unsigned char hm) { struct crypto_alg *alg = tfm->__crt_alg; struct crypto4xx_alg *my_alg = crypto_alg_to_crypto4xx_alg(alg); struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); struct dynamic_sa_ctl *sa; struct dynamic_sa_hash160 *sa_in; int rc; ctx->dev = my_alg->dev; ctx->is_hash = 1; ctx->hash_final = 0; /* Create SA */ if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr) crypto4xx_free_sa(ctx); rc = crypto4xx_alloc_sa(ctx, sa_len); if (rc) return rc; if (ctx->state_record_dma_addr == 0) { crypto4xx_alloc_state_record(ctx); if (!ctx->state_record_dma_addr) { crypto4xx_free_sa(ctx); return -ENOMEM; } } crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), sizeof(struct crypto4xx_ctx)); sa = (struct dynamic_sa_ctl *) ctx->sa_in; set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV, SA_NOT_LOAD_HASH, SA_LOAD_IV_FROM_SA, SA_NO_HEADER_PROC, ha, SA_CIPHER_ALG_NULL, SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC, SA_OPCODE_HASH, DIR_INBOUND); set_dynamic_sa_command_1(sa, 0, SA_HASH_MODE_HASH, CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF, SA_SEQ_MASK_OFF, SA_MC_ENABLE, SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD, SA_NOT_COPY_HDR); ctx->direction = DIR_INBOUND; sa->sa_contents = SA_HASH160_CONTENTS; sa_in = (struct dynamic_sa_hash160 *) ctx->sa_in; /* Need to zero hash digest in SA */ memset(sa_in->inner_digest, 0, sizeof(sa_in->inner_digest)); memset(sa_in->outer_digest, 0, sizeof(sa_in->outer_digest)); sa_in->state_ptr = ctx->state_record_dma_addr; ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx); return 0; }
/** * AES Functions */ static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int keylen, unsigned char cm, u8 fb) { struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); struct dynamic_sa_ctl *sa; int rc; if (keylen != AES_KEYSIZE_256 && keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_128) { crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } /* Create SA */ if (ctx->sa_in || ctx->sa_out) crypto4xx_free_sa(ctx); rc = crypto4xx_alloc_sa(ctx, SA_AES128_LEN + (keylen-16) / 4); if (rc) return rc; /* Setup SA */ sa = ctx->sa_in; set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV, SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE, SA_NO_HEADER_PROC, SA_HASH_ALG_NULL, SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC, SA_OPCODE_DECRYPT, DIR_INBOUND); set_dynamic_sa_command_1(sa, cm, SA_HASH_MODE_HASH, fb, SA_EXTENDED_SN_OFF, SA_SEQ_MASK_OFF, SA_MC_ENABLE, SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD, SA_NOT_COPY_HDR); crypto4xx_memcpy_to_le32(get_dynamic_sa_key_field(sa), key, keylen); sa->sa_contents.w = SA_AES_CONTENTS | (keylen << 2); sa->sa_command_1.bf.key_len = keylen >> 3; memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4); sa = ctx->sa_out; sa->sa_command_0.bf.dir = DIR_OUTBOUND; return 0; }
/** * HASH SHA1 Functions */ static int crypto4xx_hash_alg_init(struct crypto_tfm *tfm, unsigned int sa_len, unsigned char ha, unsigned char hm) { struct crypto_alg *alg = tfm->__crt_alg; struct crypto4xx_alg *my_alg; struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); struct dynamic_sa_hash160 *sa; int rc; my_alg = container_of(__crypto_ahash_alg(alg), struct crypto4xx_alg, alg.u.hash); ctx->dev = my_alg->dev; /* Create SA */ if (ctx->sa_in || ctx->sa_out) crypto4xx_free_sa(ctx); rc = crypto4xx_alloc_sa(ctx, sa_len); if (rc) return rc; crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), sizeof(struct crypto4xx_ctx)); sa = (struct dynamic_sa_hash160 *)ctx->sa_in; set_dynamic_sa_command_0(&sa->ctrl, SA_SAVE_HASH, SA_NOT_SAVE_IV, SA_NOT_LOAD_HASH, SA_LOAD_IV_FROM_SA, SA_NO_HEADER_PROC, ha, SA_CIPHER_ALG_NULL, SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC, SA_OPCODE_HASH, DIR_INBOUND); set_dynamic_sa_command_1(&sa->ctrl, 0, SA_HASH_MODE_HASH, CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF, SA_SEQ_MASK_OFF, SA_MC_ENABLE, SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD, SA_NOT_COPY_HDR); /* Need to zero hash digest in SA */ memset(sa->inner_digest, 0, sizeof(sa->inner_digest)); memset(sa->outer_digest, 0, sizeof(sa->outer_digest)); return 0; }
int crypto4xx_setkey_aes_gcm(struct crypto_aead *cipher, const u8 *key, unsigned int keylen) { struct crypto_tfm *tfm = crypto_aead_tfm(cipher); struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); struct dynamic_sa_ctl *sa; int rc = 0; if (crypto4xx_aes_gcm_validate_keylen(keylen) != 0) { crypto_aead_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } rc = crypto4xx_setup_fallback(ctx, cipher, key, keylen); if (rc) return rc; if (ctx->sa_in || ctx->sa_out) crypto4xx_free_sa(ctx); rc = crypto4xx_alloc_sa(ctx, SA_AES128_GCM_LEN + (keylen - 16) / 4); if (rc) return rc; sa = (struct dynamic_sa_ctl *) ctx->sa_in; sa->sa_contents.w = SA_AES_GCM_CONTENTS | (keylen << 2); set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV, SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE, SA_NO_HEADER_PROC, SA_HASH_ALG_GHASH, SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC, SA_OPCODE_HASH_DECRYPT, DIR_INBOUND); set_dynamic_sa_command_1(sa, CRYPTO_MODE_CTR, SA_HASH_MODE_HASH, CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF, SA_SEQ_MASK_ON, SA_MC_DISABLE, SA_NOT_COPY_PAD, SA_COPY_PAYLOAD, SA_NOT_COPY_HDR); sa->sa_command_1.bf.key_len = keylen >> 3; crypto4xx_memcpy_to_le32(get_dynamic_sa_key_field(sa), key, keylen); rc = crypto4xx_compute_gcm_hash_key_sw(get_dynamic_sa_inner_digest(sa), key, keylen); if (rc) { pr_err("GCM hash key setting failed = %d\n", rc); goto err; } memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4); sa = (struct dynamic_sa_ctl *) ctx->sa_out; sa->sa_command_0.bf.dir = DIR_OUTBOUND; sa->sa_command_0.bf.opcode = SA_OPCODE_ENCRYPT_HASH; return 0; err: crypto4xx_free_sa(ctx); return rc; }