crypto: skcipher - Add internal state support
[linux-2.6-microblaze.git] / include / crypto / skcipher.h
index ea18af4..5302f8f 100644 (file)
 #include <linux/string.h>
 #include <linux/types.h>
 
+/* Set this bit if the lskcipher operation is a continuation. */
+#define CRYPTO_LSKCIPHER_FLAG_CONT     0x00000001
+/* Set this bit if the lskcipher operation is final. */
+#define CRYPTO_LSKCIPHER_FLAG_FINAL    0x00000002
+/* The bit CRYPTO_TFM_REQ_MAY_SLEEP can also be set if needed. */
+
+/* Set this bit if the skcipher operation is a continuation. */
+#define CRYPTO_SKCIPHER_REQ_CONT       0x00000001
+/* Set this bit if the skcipher operation is not final. */
+#define CRYPTO_SKCIPHER_REQ_NOTFINAL   0x00000002
+
 struct scatterlist;
 
 /**
@@ -91,6 +102,7 @@ struct crypto_istat_cipher {
  *         IV of exactly that size to perform the encrypt or decrypt operation.
  * @chunksize: Equal to the block size except for stream ciphers such as
  *            CTR where it is set to the underlying block size.
+ * @statesize: Size of the internal state for the algorithm.
  * @stat: Statistics for cipher algorithm
  * @base: Definition of a generic crypto algorithm.
  */
@@ -99,6 +111,7 @@ struct crypto_istat_cipher {
        unsigned int max_keysize;       \
        unsigned int ivsize;            \
        unsigned int chunksize;         \
+       unsigned int statesize;         \
                                        \
        SKCIPHER_ALG_COMMON_STAT        \
                                        \
@@ -141,6 +154,17 @@ struct skcipher_alg_common SKCIPHER_ALG_COMMON;
  *          be called in parallel with the same transformation object.
  * @decrypt: Decrypt a single block. This is a reverse counterpart to @encrypt
  *          and the conditions are exactly the same.
+ * @export: Export partial state of the transformation. This function dumps the
+ *         entire state of the ongoing transformation into a provided block of
+ *         data so it can be @import 'ed back later on. This is useful in case
+ *         you want to save partial result of the transformation after
+ *         processing certain amount of data and reload this partial result
+ *         multiple times later on for multiple re-use. No data processing
+ *         happens at this point.
+ * @import: Import partial state of the transformation. This function loads the
+ *         entire state of the ongoing transformation from a provided block of
+ *         data so the transformation can continue from this point onward. No
+ *         data processing happens at this point.
  * @init: Initialize the cryptographic transformation object. This function
  *       is used to initialize the cryptographic transformation object.
  *       This function is called only once at the instantiation time, right
@@ -170,6 +194,8 @@ struct skcipher_alg {
                      unsigned int keylen);
        int (*encrypt)(struct skcipher_request *req);
        int (*decrypt)(struct skcipher_request *req);
+       int (*export)(struct skcipher_request *req, void *out);
+       int (*import)(struct skcipher_request *req, const void *in);
        int (*init)(struct crypto_skcipher *tfm);
        void (*exit)(struct crypto_skcipher *tfm);
 
@@ -200,6 +226,9 @@ struct skcipher_alg {
  *          may be left over if length is not a multiple of blocks
  *          and there is more to come (final == false).  The number of
  *          left-over bytes should be returned in case of success.
+ *          The siv field shall be as long as ivsize + statesize with
+ *          the IV placed at the front.  The state will be used by the
+ *          algorithm internally.
  * @decrypt: Decrypt a number of bytes. This is a reverse counterpart to
  *          @encrypt and the conditions are exactly the same.
  * @init: Initialize the cryptographic transformation object. This function
@@ -215,9 +244,9 @@ struct lskcipher_alg {
        int (*setkey)(struct crypto_lskcipher *tfm, const u8 *key,
                      unsigned int keylen);
        int (*encrypt)(struct crypto_lskcipher *tfm, const u8 *src,
-                      u8 *dst, unsigned len, u8 *iv, bool final);
+                      u8 *dst, unsigned len, u8 *siv, u32 flags);
        int (*decrypt)(struct crypto_lskcipher *tfm, const u8 *src,
-                      u8 *dst, unsigned len, u8 *iv, bool final);
+                      u8 *dst, unsigned len, u8 *siv, u32 flags);
        int (*init)(struct crypto_lskcipher *tfm);
        void (*exit)(struct crypto_lskcipher *tfm);
 
@@ -496,6 +525,40 @@ static inline unsigned int crypto_lskcipher_chunksize(
        return crypto_lskcipher_alg(tfm)->co.chunksize;
 }
 
+/**
+ * crypto_skcipher_statesize() - obtain state size
+ * @tfm: cipher handle
+ *
+ * Some algorithms cannot be chained with the IV alone.  They carry
+ * internal state which must be replicated if data is to be processed
+ * incrementally.  The size of that state can be obtained with this
+ * function.
+ *
+ * Return: state size in bytes
+ */
+static inline unsigned int crypto_skcipher_statesize(
+       struct crypto_skcipher *tfm)
+{
+       return crypto_skcipher_alg_common(tfm)->statesize;
+}
+
+/**
+ * crypto_lskcipher_statesize() - obtain state size
+ * @tfm: cipher handle
+ *
+ * Some algorithms cannot be chained with the IV alone.  They carry
+ * internal state which must be replicated if data is to be processed
+ * incrementally.  The size of that state can be obtained with this
+ * function.
+ *
+ * Return: state size in bytes
+ */
+static inline unsigned int crypto_lskcipher_statesize(
+       struct crypto_lskcipher *tfm)
+{
+       return crypto_lskcipher_alg(tfm)->co.statesize;
+}
+
 static inline unsigned int crypto_sync_skcipher_blocksize(
        struct crypto_sync_skcipher *tfm)
 {
@@ -689,9 +752,10 @@ int crypto_skcipher_decrypt(struct skcipher_request *req);
  * @src: source buffer
  * @dst: destination buffer
  * @len: number of bytes to process
- * @iv: IV for the cipher operation which must comply with the IV size defined
- *      by crypto_lskcipher_ivsize
- *
+ * @siv: IV + state for the cipher operation.  The length of the IV must
+ *      comply with the IV size defined by crypto_lskcipher_ivsize.  The
+ *      IV is then followed with a buffer with the length as specified by
+ *      crypto_lskcipher_statesize.
  * Encrypt plaintext data using the lskcipher handle.
  *
  * Return: >=0 if the cipher operation was successful, if positive
@@ -699,7 +763,7 @@ int crypto_skcipher_decrypt(struct skcipher_request *req);
  *        < 0 if an error occurred
  */
 int crypto_lskcipher_encrypt(struct crypto_lskcipher *tfm, const u8 *src,
-                            u8 *dst, unsigned len, u8 *iv);
+                            u8 *dst, unsigned len, u8 *siv);
 
 /**
  * crypto_lskcipher_decrypt() - decrypt ciphertext
@@ -707,8 +771,10 @@ int crypto_lskcipher_encrypt(struct crypto_lskcipher *tfm, const u8 *src,
  * @src: source buffer
  * @dst: destination buffer
  * @len: number of bytes to process
- * @iv: IV for the cipher operation which must comply with the IV size defined
- *      by crypto_lskcipher_ivsize
+ * @siv: IV + state for the cipher operation.  The length of the IV must
+ *      comply with the IV size defined by crypto_lskcipher_ivsize.  The
+ *      IV is then followed with a buffer with the length as specified by
+ *      crypto_lskcipher_statesize.
  *
  * Decrypt ciphertext data using the lskcipher handle.
  *
@@ -717,7 +783,7 @@ int crypto_lskcipher_encrypt(struct crypto_lskcipher *tfm, const u8 *src,
  *        < 0 if an error occurred
  */
 int crypto_lskcipher_decrypt(struct crypto_lskcipher *tfm, const u8 *src,
-                            u8 *dst, unsigned len, u8 *iv);
+                            u8 *dst, unsigned len, u8 *siv);
 
 /**
  * DOC: Symmetric Key Cipher Request Handle