return 0;
}
-#ifdef EXPORT_FIXED
-static int ssi_hash_export(struct ssi_hash_ctx *ctx, void *out)
-{
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
- memcpy(out, ctx, sizeof(struct ssi_hash_ctx));
- return 0;
-}
-
-static int ssi_hash_import(struct ssi_hash_ctx *ctx, const void *in)
-{
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
- memcpy(ctx, in, sizeof(struct ssi_hash_ctx));
- return 0;
-}
-#endif
-
static int ssi_hash_setkey(void *hash,
const u8 *key,
unsigned int keylen,
return ssi_hash_init(state, ctx);
}
-#ifdef EXPORT_FIXED
static int ssi_ahash_export(struct ahash_request *req, void *out)
{
struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash);
+ struct device *dev = &ctx->drvdata->plat_dev->dev;
+ struct ahash_req_ctx *state = ahash_request_ctx(req);
+ u8 *curr_buff = state->buff_index ? state->buff1 : state->buff0;
+ u32 curr_buff_cnt = state->buff_index ? state->buff1_cnt :
+ state->buff0_cnt;
+ const u32 tmp = CC_EXPORT_MAGIC;
+
+ CHECK_AND_RETURN_UPON_FIPS_ERROR();
- return ssi_hash_export(ctx, out);
+ memcpy(out, &tmp, sizeof(u32));
+ out += sizeof(u32);
+
+ dma_sync_single_for_cpu(dev, state->digest_buff_dma_addr,
+ ctx->inter_digestsize, DMA_BIDIRECTIONAL);
+ memcpy(out, state->digest_buff, ctx->inter_digestsize);
+ out += ctx->inter_digestsize;
+
+ if (state->digest_bytes_len_dma_addr) {
+ dma_sync_single_for_cpu(dev, state->digest_bytes_len_dma_addr,
+ HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
+ memcpy(out, state->digest_bytes_len, HASH_LEN_SIZE);
+ } else {
+ /* Poison the unused exported digest len field. */
+ memset(out, 0x5F, HASH_LEN_SIZE);
+ }
+ out += HASH_LEN_SIZE;
+
+ memcpy(out, &curr_buff_cnt, sizeof(u32));
+ out += sizeof(u32);
+
+ memcpy(out, curr_buff, curr_buff_cnt);
+
+ /* No sync for device ineeded since we did not change the data,
+ * we only copy it
+ */
+
+ return 0;
}
static int ssi_ahash_import(struct ahash_request *req, const void *in)
{
struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash);
+ struct device *dev = &ctx->drvdata->plat_dev->dev;
+ struct ahash_req_ctx *state = ahash_request_ctx(req);
+ u32 tmp;
+ int rc;
+
+ CHECK_AND_RETURN_UPON_FIPS_ERROR();
- return ssi_hash_import(ctx, in);
+ memcpy(&tmp, in, sizeof(u32));
+ if (tmp != CC_EXPORT_MAGIC) {
+ rc = -EINVAL;
+ goto out;
+ }
+ in += sizeof(u32);
+
+ rc = ssi_hash_init(state, ctx);
+ if (rc)
+ goto out;
+
+ dma_sync_single_for_cpu(dev, state->digest_buff_dma_addr,
+ ctx->inter_digestsize, DMA_BIDIRECTIONAL);
+ memcpy(state->digest_buff, in, ctx->inter_digestsize);
+ in += ctx->inter_digestsize;
+
+ if (state->digest_bytes_len_dma_addr) {
+ dma_sync_single_for_cpu(dev, state->digest_bytes_len_dma_addr,
+ HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
+ memcpy(state->digest_bytes_len, in, HASH_LEN_SIZE);
+ }
+ in += HASH_LEN_SIZE;
+
+ dma_sync_single_for_device(dev, state->digest_buff_dma_addr,
+ ctx->inter_digestsize, DMA_BIDIRECTIONAL);
+
+ if (state->digest_bytes_len_dma_addr)
+ dma_sync_single_for_device(dev,
+ state->digest_bytes_len_dma_addr,
+ HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
+
+ state->buff_index = 0;
+
+ /* Sanity check the data as much as possible */
+ memcpy(&tmp, in, sizeof(u32));
+ if (tmp > SSI_MAX_HASH_BLCK_SIZE) {
+ rc = -EINVAL;
+ goto out;
+ }
+ in += sizeof(u32);
+
+ state->buff0_cnt = tmp;
+ memcpy(state->buff0, in, state->buff0_cnt);
+
+out:
+ return rc;
}
-#endif
static int ssi_ahash_setkey(struct crypto_ahash *ahash,
const u8 *key, unsigned int keylen)
struct ssi_drvdata *drvdata;
};
+#define CC_STATE_SIZE(_x) \
+ ((_x) + HASH_LEN_SIZE + SSI_MAX_HASH_BLCK_SIZE + (2 * sizeof(u32)))
+
/* hash descriptors */
static struct ssi_hash_template driver_hash[] = {
//Asynchronize hash template
.final = ssi_ahash_final,
.finup = ssi_ahash_finup,
.digest = ssi_ahash_digest,
-#ifdef EXPORT_FIXED
.export = ssi_ahash_export,
.import = ssi_ahash_import,
-#endif
.setkey = ssi_ahash_setkey,
.halg = {
.digestsize = SHA1_DIGEST_SIZE,
- .statesize = sizeof(struct sha1_state),
+ .statesize = CC_STATE_SIZE(SHA1_DIGEST_SIZE),
},
},
.hash_mode = DRV_HASH_SHA1,
.final = ssi_ahash_final,
.finup = ssi_ahash_finup,
.digest = ssi_ahash_digest,
-#ifdef EXPORT_FIXED
.export = ssi_ahash_export,
.import = ssi_ahash_import,
-#endif
.setkey = ssi_ahash_setkey,
.halg = {
.digestsize = SHA256_DIGEST_SIZE,
- .statesize = sizeof(struct sha256_state),
+ .statesize = CC_STATE_SIZE(SHA256_DIGEST_SIZE)
},
},
.hash_mode = DRV_HASH_SHA256,
.final = ssi_ahash_final,
.finup = ssi_ahash_finup,
.digest = ssi_ahash_digest,
-#ifdef EXPORT_FIXED
.export = ssi_ahash_export,
.import = ssi_ahash_import,
-#endif
.setkey = ssi_ahash_setkey,
.halg = {
.digestsize = SHA224_DIGEST_SIZE,
- .statesize = sizeof(struct sha256_state),
+ .statesize = CC_STATE_SIZE(SHA224_DIGEST_SIZE),
},
},
.hash_mode = DRV_HASH_SHA224,
.final = ssi_ahash_final,
.finup = ssi_ahash_finup,
.digest = ssi_ahash_digest,
-#ifdef EXPORT_FIXED
.export = ssi_ahash_export,
.import = ssi_ahash_import,
-#endif
.setkey = ssi_ahash_setkey,
.halg = {
.digestsize = SHA384_DIGEST_SIZE,
- .statesize = sizeof(struct sha512_state),
+ .statesize = CC_STATE_SIZE(SHA384_DIGEST_SIZE),
},
},
.hash_mode = DRV_HASH_SHA384,
.final = ssi_ahash_final,
.finup = ssi_ahash_finup,
.digest = ssi_ahash_digest,
-#ifdef EXPORT_FIXED
.export = ssi_ahash_export,
.import = ssi_ahash_import,
-#endif
.setkey = ssi_ahash_setkey,
.halg = {
.digestsize = SHA512_DIGEST_SIZE,
- .statesize = sizeof(struct sha512_state),
+ .statesize = CC_STATE_SIZE(SHA512_DIGEST_SIZE),
},
},
.hash_mode = DRV_HASH_SHA512,
.final = ssi_ahash_final,
.finup = ssi_ahash_finup,
.digest = ssi_ahash_digest,
-#ifdef EXPORT_FIXED
.export = ssi_ahash_export,
.import = ssi_ahash_import,
-#endif
.setkey = ssi_ahash_setkey,
.halg = {
.digestsize = MD5_DIGEST_SIZE,
- .statesize = sizeof(struct md5_state),
+ .statesize = CC_STATE_SIZE(MD5_DIGEST_SIZE),
},
},
.hash_mode = DRV_HASH_MD5,
.finup = ssi_mac_finup,
.digest = ssi_mac_digest,
.setkey = ssi_xcbc_setkey,
-#ifdef EXPORT_FIXED
.export = ssi_ahash_export,
.import = ssi_ahash_import,
-#endif
.halg = {
.digestsize = AES_BLOCK_SIZE,
- .statesize = sizeof(struct aeshash_state),
+ .statesize = CC_STATE_SIZE(AES_BLOCK_SIZE),
},
},
.hash_mode = DRV_HASH_NULL,
.finup = ssi_mac_finup,
.digest = ssi_mac_digest,
.setkey = ssi_cmac_setkey,
-#ifdef EXPORT_FIXED
.export = ssi_ahash_export,
.import = ssi_ahash_import,
-#endif
.halg = {
.digestsize = AES_BLOCK_SIZE,
- .statesize = sizeof(struct aeshash_state),
+ .statesize = CC_STATE_SIZE(AES_BLOCK_SIZE),
},
},
.hash_mode = DRV_HASH_NULL,