[dif] Implement the AES OFB and CFB modes on the DIF API
Signed-off-by: Douglas Reis <doreis@lowrisc.org>
diff --git a/sw/device/lib/dif/dif_aes.c b/sw/device/lib/dif/dif_aes.c
index 7958a95..fc2b519 100644
--- a/sw/device/lib/dif/dif_aes.c
+++ b/sw/device/lib/dif/dif_aes.c
@@ -291,6 +291,60 @@
return kDifOk;
}
+dif_result_t dif_aes_start_ofb(const dif_aes_t *aes,
+ const dif_aes_transaction_t *transaction,
+ dif_aes_key_share_t key, dif_aes_iv_t iv) {
+ if (aes == NULL || transaction == NULL) {
+ return kDifBadArg;
+ }
+
+ if (!aes_idle(aes)) {
+ return kDifUnavailable;
+ }
+
+ dif_result_t result = configure(aes, transaction, kAesModeFieldValOfb);
+ if (result != kDifOk) {
+ return result;
+ }
+
+ aes_set_multireg(aes, &key.share0[0], AES_KEY_SHARE0_MULTIREG_COUNT,
+ AES_KEY_SHARE0_0_REG_OFFSET);
+
+ aes_set_multireg(aes, &key.share1[0], AES_KEY_SHARE1_MULTIREG_COUNT,
+ AES_KEY_SHARE1_0_REG_OFFSET);
+
+ aes_set_multireg(aes, &iv.iv[0], AES_IV_MULTIREG_COUNT, AES_IV_0_REG_OFFSET);
+
+ return kDifOk;
+}
+
+dif_result_t dif_aes_start_cfb(const dif_aes_t *aes,
+ const dif_aes_transaction_t *transaction,
+ dif_aes_key_share_t key, dif_aes_iv_t iv) {
+ if (aes == NULL || transaction == NULL) {
+ return kDifBadArg;
+ }
+
+ if (!aes_idle(aes)) {
+ return kDifUnavailable;
+ }
+
+ dif_result_t result = configure(aes, transaction, kAesModeFieldValCfb);
+ if (result != kDifOk) {
+ return result;
+ }
+
+ aes_set_multireg(aes, &key.share0[0], AES_KEY_SHARE0_MULTIREG_COUNT,
+ AES_KEY_SHARE0_0_REG_OFFSET);
+
+ aes_set_multireg(aes, &key.share1[0], AES_KEY_SHARE1_MULTIREG_COUNT,
+ AES_KEY_SHARE1_0_REG_OFFSET);
+
+ aes_set_multireg(aes, &iv.iv[0], AES_IV_MULTIREG_COUNT, AES_IV_0_REG_OFFSET);
+
+ return kDifOk;
+}
+
dif_result_t dif_aes_end(const dif_aes_t *aes) {
if (aes == NULL) {
return kDifBadArg;
diff --git a/sw/device/lib/dif/dif_aes.h b/sw/device/lib/dif/dif_aes.h
index e1d4b0b..65e767c 100644
--- a/sw/device/lib/dif/dif_aes.h
+++ b/sw/device/lib/dif/dif_aes.h
@@ -245,6 +245,59 @@
dif_aes_key_share_t key, dif_aes_iv_t iv);
/**
+ * Begins an AES transaction in OFB mode.
+ *
+ * In OFB cipher mode, the same key can be used for all messages, and the
+ * Initialization Vector (IV) need NOT be unpredictable. The following
+ * conditions must be true:
+ * OFB mode requires a unique initialization vector for every message that
+ * is ever encrypted under a given key, across all messages.
+ *
+ * With key length less than 256 bits, the excess portion of the `key` can be
+ * written with any data (preferably random).
+ *
+ * The peripheral must be in IDLE state for this operation to take effect, and
+ * will return `kDifAesStartBusy` if this condition is not met.
+ *
+ * @param aes AES state data.
+ * @param transaction Configuration data.
+ * @param key Masked AES key.
+ * @param iv AES Initialization vector.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_aes_start_ofb(const dif_aes_t *aes,
+ const dif_aes_transaction_t *transaction,
+ dif_aes_key_share_t key, dif_aes_iv_t iv);
+
+/**
+ * Begins an AES transaction in CFB mode.
+ *
+ * In CFB cipher mode, the same key can be used for all messages, however
+ * new Initialisation Vector (IV) must be generated for any new message. The
+ * following condition must be true:
+ * The IV must be unpredictable (it must not be possible to predict the IV
+ * that will be associated to the plaintext in advance of the generation of
+ * the IV).
+ *
+ * With key length less than 256 bits, the excess portion of the `key` can be
+ * written with any data (preferably random).
+ *
+ * The peripheral must be in IDLE state for this operation to take effect, and
+ * will return `kDifAesStartBusy` if this condition is not met.
+ *
+ * @param aes AES state data.
+ * @param transaction Configuration data.
+ * @param key Masked AES key.
+ * @param iv AES Initialization vector.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_aes_start_cfb(const dif_aes_t *aes,
+ const dif_aes_transaction_t *transaction,
+ dif_aes_key_share_t key, dif_aes_iv_t iv);
+
+/**
* Ends an AES transaction.
*
* This function must be called at the end of every `dif_aes_<mode>_start`