diff options
Diffstat (limited to 'crypto/lrw.c')
-rw-r--r-- | crypto/lrw.c | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/crypto/lrw.c b/crypto/lrw.c index bee60226f723..91c17fa18374 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c | |||
@@ -29,8 +29,7 @@ | |||
29 | 29 | ||
30 | #define LRW_BLOCK_SIZE 16 | 30 | #define LRW_BLOCK_SIZE 16 |
31 | 31 | ||
32 | struct priv { | 32 | struct lrw_table_ctx { |
33 | struct crypto_cipher *child; | ||
34 | /* optimizes multiplying a random (non incrementing, as at the | 33 | /* optimizes multiplying a random (non incrementing, as at the |
35 | * start of a new sector) value with key2, we could also have | 34 | * start of a new sector) value with key2, we could also have |
36 | * used 4k optimization tables or no optimization at all. In the | 35 | * used 4k optimization tables or no optimization at all. In the |
@@ -45,6 +44,11 @@ struct priv { | |||
45 | be128 mulinc[128]; | 44 | be128 mulinc[128]; |
46 | }; | 45 | }; |
47 | 46 | ||
47 | struct priv { | ||
48 | struct crypto_cipher *child; | ||
49 | struct lrw_table_ctx table; | ||
50 | }; | ||
51 | |||
48 | static inline void setbit128_bbe(void *b, int bit) | 52 | static inline void setbit128_bbe(void *b, int bit) |
49 | { | 53 | { |
50 | __set_bit(bit ^ (0x80 - | 54 | __set_bit(bit ^ (0x80 - |
@@ -56,28 +60,16 @@ static inline void setbit128_bbe(void *b, int bit) | |||
56 | ), b); | 60 | ), b); |
57 | } | 61 | } |
58 | 62 | ||
59 | static int setkey(struct crypto_tfm *parent, const u8 *key, | 63 | static int lrw_init_table(struct lrw_table_ctx *ctx, const u8 *tweak) |
60 | unsigned int keylen) | ||
61 | { | 64 | { |
62 | struct priv *ctx = crypto_tfm_ctx(parent); | ||
63 | struct crypto_cipher *child = ctx->child; | ||
64 | int err, i; | ||
65 | be128 tmp = { 0 }; | 65 | be128 tmp = { 0 }; |
66 | int bsize = LRW_BLOCK_SIZE; | 66 | int i; |
67 | |||
68 | crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); | ||
69 | crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) & | ||
70 | CRYPTO_TFM_REQ_MASK); | ||
71 | if ((err = crypto_cipher_setkey(child, key, keylen - bsize))) | ||
72 | return err; | ||
73 | crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) & | ||
74 | CRYPTO_TFM_RES_MASK); | ||
75 | 67 | ||
76 | if (ctx->table) | 68 | if (ctx->table) |
77 | gf128mul_free_64k(ctx->table); | 69 | gf128mul_free_64k(ctx->table); |
78 | 70 | ||
79 | /* initialize multiplication table for Key2 */ | 71 | /* initialize multiplication table for Key2 */ |
80 | ctx->table = gf128mul_init_64k_bbe((be128 *)(key + keylen - bsize)); | 72 | ctx->table = gf128mul_init_64k_bbe((be128 *)tweak); |
81 | if (!ctx->table) | 73 | if (!ctx->table) |
82 | return -ENOMEM; | 74 | return -ENOMEM; |
83 | 75 | ||
@@ -91,6 +83,32 @@ static int setkey(struct crypto_tfm *parent, const u8 *key, | |||
91 | return 0; | 83 | return 0; |
92 | } | 84 | } |
93 | 85 | ||
86 | static void lrw_free_table(struct lrw_table_ctx *ctx) | ||
87 | { | ||
88 | if (ctx->table) | ||
89 | gf128mul_free_64k(ctx->table); | ||
90 | } | ||
91 | |||
92 | static int setkey(struct crypto_tfm *parent, const u8 *key, | ||
93 | unsigned int keylen) | ||
94 | { | ||
95 | struct priv *ctx = crypto_tfm_ctx(parent); | ||
96 | struct crypto_cipher *child = ctx->child; | ||
97 | int err, bsize = LRW_BLOCK_SIZE; | ||
98 | const u8 *tweak = key + keylen - bsize; | ||
99 | |||
100 | crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); | ||
101 | crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) & | ||
102 | CRYPTO_TFM_REQ_MASK); | ||
103 | err = crypto_cipher_setkey(child, key, keylen - bsize); | ||
104 | if (err) | ||
105 | return err; | ||
106 | crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) & | ||
107 | CRYPTO_TFM_RES_MASK); | ||
108 | |||
109 | return lrw_init_table(&ctx->table, tweak); | ||
110 | } | ||
111 | |||
94 | struct sinfo { | 112 | struct sinfo { |
95 | be128 t; | 113 | be128 t; |
96 | struct crypto_tfm *tfm; | 114 | struct crypto_tfm *tfm; |
@@ -157,7 +175,7 @@ static int crypt(struct blkcipher_desc *d, | |||
157 | s.t = *iv; | 175 | s.t = *iv; |
158 | 176 | ||
159 | /* T <- I*Key2 */ | 177 | /* T <- I*Key2 */ |
160 | gf128mul_64k_bbe(&s.t, ctx->table); | 178 | gf128mul_64k_bbe(&s.t, ctx->table.table); |
161 | 179 | ||
162 | goto first; | 180 | goto first; |
163 | 181 | ||
@@ -165,7 +183,8 @@ static int crypt(struct blkcipher_desc *d, | |||
165 | do { | 183 | do { |
166 | /* T <- I*Key2, using the optimization | 184 | /* T <- I*Key2, using the optimization |
167 | * discussed in the specification */ | 185 | * discussed in the specification */ |
168 | be128_xor(&s.t, &s.t, &ctx->mulinc[get_index128(iv)]); | 186 | be128_xor(&s.t, &s.t, |
187 | &ctx->table.mulinc[get_index128(iv)]); | ||
169 | inc(iv); | 188 | inc(iv); |
170 | 189 | ||
171 | first: | 190 | first: |
@@ -233,8 +252,8 @@ static int init_tfm(struct crypto_tfm *tfm) | |||
233 | static void exit_tfm(struct crypto_tfm *tfm) | 252 | static void exit_tfm(struct crypto_tfm *tfm) |
234 | { | 253 | { |
235 | struct priv *ctx = crypto_tfm_ctx(tfm); | 254 | struct priv *ctx = crypto_tfm_ctx(tfm); |
236 | if (ctx->table) | 255 | |
237 | gf128mul_free_64k(ctx->table); | 256 | lrw_free_table(&ctx->table); |
238 | crypto_free_cipher(ctx->child); | 257 | crypto_free_cipher(ctx->child); |
239 | } | 258 | } |
240 | 259 | ||