aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMilan Broz <mbroz@redhat.com>2010-08-11 23:14:07 -0400
committerAlasdair G Kergon <agk@redhat.com>2010-08-11 23:14:07 -0400
commit5ebaee6d290279d1df6ce45d6d54de8cfc473273 (patch)
tree9fa2693bcd1f46827e90f1aff1d36fd1d6da4ea6 /drivers/md
parent28513fccf0ceefb8171ddc0cefa429b82e92a2c9 (diff)
dm crypt: simplify crypt_ctr
Allocate cipher strings indpendently of struct crypt_config and move cipher parsing and allocation into a separate function to prepare for supporting the cryptoapi format e.g. "xts(aes)". No functional change in this patch. Signed-off-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-crypt.c185
1 files changed, 104 insertions, 81 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 139bbe2254cd..6401bfa0adff 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -107,11 +107,10 @@ struct crypt_config {
107 struct workqueue_struct *io_queue; 107 struct workqueue_struct *io_queue;
108 struct workqueue_struct *crypt_queue; 108 struct workqueue_struct *crypt_queue;
109 109
110 /* 110 char *cipher;
111 * crypto related data 111 char *cipher_mode;
112 */ 112
113 struct crypt_iv_operations *iv_gen_ops; 113 struct crypt_iv_operations *iv_gen_ops;
114 char *iv_mode;
115 union { 114 union {
116 struct iv_essiv_private essiv; 115 struct iv_essiv_private essiv;
117 struct iv_benbi_private benbi; 116 struct iv_benbi_private benbi;
@@ -135,8 +134,6 @@ struct crypt_config {
135 unsigned int dmreq_start; 134 unsigned int dmreq_start;
136 struct ablkcipher_request *req; 135 struct ablkcipher_request *req;
137 136
138 char cipher[CRYPTO_MAX_ALG_NAME];
139 char chainmode[CRYPTO_MAX_ALG_NAME];
140 struct crypto_ablkcipher *tfm; 137 struct crypto_ablkcipher *tfm;
141 unsigned long flags; 138 unsigned long flags;
142 unsigned int key_size; 139 unsigned int key_size;
@@ -1032,90 +1029,102 @@ static void crypt_dtr(struct dm_target *ti)
1032 if (cc->dev) 1029 if (cc->dev)
1033 dm_put_device(ti, cc->dev); 1030 dm_put_device(ti, cc->dev);
1034 1031
1035 kfree(cc->iv_mode); 1032 kzfree(cc->cipher);
1033 kzfree(cc->cipher_mode);
1036 1034
1037 /* Must zero key material before freeing */ 1035 /* Must zero key material before freeing */
1038 kzfree(cc); 1036 kzfree(cc);
1039} 1037}
1040 1038
1041/* 1039static int crypt_ctr_cipher(struct dm_target *ti,
1042 * Construct an encryption mapping: 1040 char *cipher_in, char *key)
1043 * <cipher> <key> <iv_offset> <dev_path> <start>
1044 */
1045static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1046{ 1041{
1047 struct crypt_config *cc; 1042 struct crypt_config *cc = ti->private;
1048 char *tmp; 1043 char *tmp, *cipher, *chainmode, *ivmode, *ivopts;
1049 char *cipher; 1044 char *cipher_api = NULL;
1050 char *chainmode;
1051 char *ivmode;
1052 char *ivopts;
1053 unsigned int key_size;
1054 unsigned long long tmpll;
1055 int ret = -EINVAL; 1045 int ret = -EINVAL;
1056 1046
1057 if (argc != 5) { 1047 /* Convert to crypto api definition? */
1058 ti->error = "Not enough arguments"; 1048 if (strchr(cipher_in, '(')) {
1049 ti->error = "Bad cipher specification";
1059 return -EINVAL; 1050 return -EINVAL;
1060 } 1051 }
1061 1052
1062 tmp = argv[0]; 1053 /*
1054 * Legacy dm-crypt cipher specification
1055 * cipher-mode-iv:ivopts
1056 */
1057 tmp = cipher_in;
1063 cipher = strsep(&tmp, "-"); 1058 cipher = strsep(&tmp, "-");
1059
1060 cc->cipher = kstrdup(cipher, GFP_KERNEL);
1061 if (!cc->cipher)
1062 goto bad_mem;
1063
1064 if (tmp) {
1065 cc->cipher_mode = kstrdup(tmp, GFP_KERNEL);
1066 if (!cc->cipher_mode)
1067 goto bad_mem;
1068 }
1069
1064 chainmode = strsep(&tmp, "-"); 1070 chainmode = strsep(&tmp, "-");
1065 ivopts = strsep(&tmp, "-"); 1071 ivopts = strsep(&tmp, "-");
1066 ivmode = strsep(&ivopts, ":"); 1072 ivmode = strsep(&ivopts, ":");
1067 1073
1068 if (tmp) 1074 if (tmp)
1069 DMWARN("Unexpected additional cipher options"); 1075 DMWARN("Ignoring unexpected additional cipher options");
1070 1076
1071 key_size = strlen(argv[1]) >> 1; 1077 /* Compatibility mode for old dm-crypt mappings */
1072 1078 if (!chainmode || (!strcmp(chainmode, "plain") && !ivmode)) {
1073 cc = kzalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL); 1079 kfree(cc->cipher_mode);
1074 if (!cc) { 1080 cc->cipher_mode = kstrdup("cbc-plain", GFP_KERNEL);
1075 ti->error = "Cannot allocate transparent encryption context";
1076 return -ENOMEM;
1077 }
1078
1079 ti->private = cc;
1080
1081 /* Compatibility mode for old dm-crypt cipher strings */
1082 if (!chainmode || (strcmp(chainmode, "plain") == 0 && !ivmode)) {
1083 chainmode = "cbc"; 1081 chainmode = "cbc";
1084 ivmode = "plain"; 1082 ivmode = "plain";
1085 } 1083 }
1086 1084
1087 if (strcmp(chainmode, "ecb") && !ivmode) { 1085 if (strcmp(chainmode, "ecb") && !ivmode) {
1088 ti->error = "This chaining mode requires an IV mechanism"; 1086 ti->error = "IV mechanism required";
1089 goto bad; 1087 return -EINVAL;
1090 } 1088 }
1091 1089
1092 ret = -ENOMEM; 1090 cipher_api = kmalloc(CRYPTO_MAX_ALG_NAME, GFP_KERNEL);
1093 if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)", 1091 if (!cipher_api)
1094 chainmode, cipher) >= CRYPTO_MAX_ALG_NAME) { 1092 goto bad_mem;
1095 ti->error = "Chain mode + cipher name is too long"; 1093
1096 goto bad; 1094 ret = snprintf(cipher_api, CRYPTO_MAX_ALG_NAME,
1095 "%s(%s)", chainmode, cipher);
1096 if (ret < 0) {
1097 kfree(cipher_api);
1098 goto bad_mem;
1097 } 1099 }
1098 1100
1099 cc->tfm = crypto_alloc_ablkcipher(cc->cipher, 0, 0); 1101 /* Allocate cipher */
1102 cc->tfm = crypto_alloc_ablkcipher(cipher_api, 0, 0);
1100 if (IS_ERR(cc->tfm)) { 1103 if (IS_ERR(cc->tfm)) {
1104 ret = PTR_ERR(cc->tfm);
1101 ti->error = "Error allocating crypto tfm"; 1105 ti->error = "Error allocating crypto tfm";
1102 goto bad; 1106 goto bad;
1103 } 1107 }
1104 1108
1105 strcpy(cc->cipher, cipher); 1109 /* Initialize and set key */
1106 strcpy(cc->chainmode, chainmode); 1110 ret = crypt_set_key(cc, key);
1107
1108 ret = crypt_set_key(cc, argv[1]);
1109 if (ret < 0) { 1111 if (ret < 0) {
1110 ti->error = "Error decoding and setting key"; 1112 ti->error = "Error decoding and setting key";
1111 goto bad; 1113 goto bad;
1112 } 1114 }
1113 1115
1114 /* 1116 /* Initialize IV */
1115 * Choose ivmode. Valid modes: "plain", "essiv:<esshash>", "benbi". 1117 cc->iv_size = crypto_ablkcipher_ivsize(cc->tfm);
1116 * See comments at iv code 1118 if (cc->iv_size)
1117 */ 1119 /* at least a 64 bit sector number should fit in our buffer */
1118 ret = -EINVAL; 1120 cc->iv_size = max(cc->iv_size,
1121 (unsigned int)(sizeof(u64) / sizeof(u8)));
1122 else if (ivmode) {
1123 DMWARN("Selected cipher does not support IVs");
1124 ivmode = NULL;
1125 }
1126
1127 /* Choose ivmode, see comments at iv code. */
1119 if (ivmode == NULL) 1128 if (ivmode == NULL)
1120 cc->iv_gen_ops = NULL; 1129 cc->iv_gen_ops = NULL;
1121 else if (strcmp(ivmode, "plain") == 0) 1130 else if (strcmp(ivmode, "plain") == 0)
@@ -1129,6 +1138,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1129 else if (strcmp(ivmode, "null") == 0) 1138 else if (strcmp(ivmode, "null") == 0)
1130 cc->iv_gen_ops = &crypt_iv_null_ops; 1139 cc->iv_gen_ops = &crypt_iv_null_ops;
1131 else { 1140 else {
1141 ret = -EINVAL;
1132 ti->error = "Invalid IV mode"; 1142 ti->error = "Invalid IV mode";
1133 goto bad; 1143 goto bad;
1134 } 1144 }
@@ -1151,20 +1161,45 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1151 } 1161 }
1152 } 1162 }
1153 1163
1154 cc->iv_size = crypto_ablkcipher_ivsize(cc->tfm); 1164 ret = 0;
1155 if (cc->iv_size) 1165bad:
1156 /* at least a 64 bit sector number should fit in our buffer */ 1166 kfree(cipher_api);
1157 cc->iv_size = max(cc->iv_size, 1167 return ret;
1158 (unsigned int)(sizeof(u64) / sizeof(u8))); 1168
1159 else { 1169bad_mem:
1160 if (cc->iv_gen_ops) { 1170 ti->error = "Cannot allocate cipher strings";
1161 DMWARN("Selected cipher does not support IVs"); 1171 return -ENOMEM;
1162 if (cc->iv_gen_ops->dtr) 1172}
1163 cc->iv_gen_ops->dtr(cc); 1173
1164 cc->iv_gen_ops = NULL; 1174/*
1165 } 1175 * Construct an encryption mapping:
1176 * <cipher> <key> <iv_offset> <dev_path> <start>
1177 */
1178static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1179{
1180 struct crypt_config *cc;
1181 unsigned int key_size;
1182 unsigned long long tmpll;
1183 int ret;
1184
1185 if (argc != 5) {
1186 ti->error = "Not enough arguments";
1187 return -EINVAL;
1166 } 1188 }
1167 1189
1190 key_size = strlen(argv[1]) >> 1;
1191
1192 cc = kzalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
1193 if (!cc) {
1194 ti->error = "Cannot allocate encryption context";
1195 return -ENOMEM;
1196 }
1197
1198 ti->private = cc;
1199 ret = crypt_ctr_cipher(ti, argv[0], argv[1]);
1200 if (ret < 0)
1201 goto bad;
1202
1168 ret = -ENOMEM; 1203 ret = -ENOMEM;
1169 cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool); 1204 cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool);
1170 if (!cc->io_pool) { 1205 if (!cc->io_pool) {
@@ -1217,17 +1252,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1217 cc->start = tmpll; 1252 cc->start = tmpll;
1218 1253
1219 ret = -ENOMEM; 1254 ret = -ENOMEM;
1220 if (ivmode && cc->iv_gen_ops) {
1221 if (ivopts)
1222 *(ivopts - 1) = ':';
1223 cc->iv_mode = kstrdup(ivmode, GFP_KERNEL);
1224 if (!cc->iv_mode) {
1225 ti->error = "Error kmallocing iv_mode string";
1226 goto bad;
1227 }
1228 } else
1229 cc->iv_mode = NULL;
1230
1231 cc->io_queue = create_singlethread_workqueue("kcryptd_io"); 1255 cc->io_queue = create_singlethread_workqueue("kcryptd_io");
1232 if (!cc->io_queue) { 1256 if (!cc->io_queue) {
1233 ti->error = "Couldn't create kcryptd io queue"; 1257 ti->error = "Couldn't create kcryptd io queue";
@@ -1273,7 +1297,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
1273static int crypt_status(struct dm_target *ti, status_type_t type, 1297static int crypt_status(struct dm_target *ti, status_type_t type,
1274 char *result, unsigned int maxlen) 1298 char *result, unsigned int maxlen)
1275{ 1299{
1276 struct crypt_config *cc = (struct crypt_config *) ti->private; 1300 struct crypt_config *cc = ti->private;
1277 unsigned int sz = 0; 1301 unsigned int sz = 0;
1278 1302
1279 switch (type) { 1303 switch (type) {
@@ -1282,11 +1306,10 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
1282 break; 1306 break;
1283 1307
1284 case STATUSTYPE_TABLE: 1308 case STATUSTYPE_TABLE:
1285 if (cc->iv_mode) 1309 if (cc->cipher_mode)
1286 DMEMIT("%s-%s-%s ", cc->cipher, cc->chainmode, 1310 DMEMIT("%s-%s ", cc->cipher, cc->cipher_mode);
1287 cc->iv_mode);
1288 else 1311 else
1289 DMEMIT("%s-%s ", cc->cipher, cc->chainmode); 1312 DMEMIT("%s ", cc->cipher);
1290 1313
1291 if (cc->key_size > 0) { 1314 if (cc->key_size > 0) {
1292 if ((maxlen - sz) < ((cc->key_size << 1) + 1)) 1315 if ((maxlen - sz) < ((cc->key_size << 1) + 1))