Commit 5ebaee6d290279d1df6ce45d6d54de8cfc473273

Authored by Milan Broz
Committed by Alasdair G Kergon
1 parent 28513fccf0

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>

Showing 1 changed file with 104 additions and 81 deletions Side-by-side Diff

drivers/md/dm-crypt.c
... ... @@ -107,11 +107,10 @@
107 107 struct workqueue_struct *io_queue;
108 108 struct workqueue_struct *crypt_queue;
109 109  
110   - /*
111   - * crypto related data
112   - */
  110 + char *cipher;
  111 + char *cipher_mode;
  112 +
113 113 struct crypt_iv_operations *iv_gen_ops;
114   - char *iv_mode;
115 114 union {
116 115 struct iv_essiv_private essiv;
117 116 struct iv_benbi_private benbi;
... ... @@ -135,8 +134,6 @@
135 134 unsigned int dmreq_start;
136 135 struct ablkcipher_request *req;
137 136  
138   - char cipher[CRYPTO_MAX_ALG_NAME];
139   - char chainmode[CRYPTO_MAX_ALG_NAME];
140 137 struct crypto_ablkcipher *tfm;
141 138 unsigned long flags;
142 139 unsigned int key_size;
143 140  
144 141  
145 142  
146 143  
147 144  
148 145  
149 146  
150 147  
151 148  
152 149  
153 150  
154 151  
155 152  
... ... @@ -1032,90 +1029,102 @@
1032 1029 if (cc->dev)
1033 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 1035 /* Must zero key material before freeing */
1038 1036 kzfree(cc);
1039 1037 }
1040 1038  
1041   -/*
1042   - * Construct an encryption mapping:
1043   - * <cipher> <key> <iv_offset> <dev_path> <start>
1044   - */
1045   -static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
  1039 +static int crypt_ctr_cipher(struct dm_target *ti,
  1040 + char *cipher_in, char *key)
1046 1041 {
1047   - struct crypt_config *cc;
1048   - char *tmp;
1049   - char *cipher;
1050   - char *chainmode;
1051   - char *ivmode;
1052   - char *ivopts;
1053   - unsigned int key_size;
1054   - unsigned long long tmpll;
  1042 + struct crypt_config *cc = ti->private;
  1043 + char *tmp, *cipher, *chainmode, *ivmode, *ivopts;
  1044 + char *cipher_api = NULL;
1055 1045 int ret = -EINVAL;
1056 1046  
1057   - if (argc != 5) {
1058   - ti->error = "Not enough arguments";
  1047 + /* Convert to crypto api definition? */
  1048 + if (strchr(cipher_in, '(')) {
  1049 + ti->error = "Bad cipher specification";
1059 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 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 1070 chainmode = strsep(&tmp, "-");
1065 1071 ivopts = strsep(&tmp, "-");
1066 1072 ivmode = strsep(&ivopts, ":");
1067 1073  
1068 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;
1072   -
1073   - cc = kzalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
1074   - if (!cc) {
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)) {
  1077 + /* Compatibility mode for old dm-crypt mappings */
  1078 + if (!chainmode || (!strcmp(chainmode, "plain") && !ivmode)) {
  1079 + kfree(cc->cipher_mode);
  1080 + cc->cipher_mode = kstrdup("cbc-plain", GFP_KERNEL);
1083 1081 chainmode = "cbc";
1084 1082 ivmode = "plain";
1085 1083 }
1086 1084  
1087 1085 if (strcmp(chainmode, "ecb") && !ivmode) {
1088   - ti->error = "This chaining mode requires an IV mechanism";
1089   - goto bad;
  1086 + ti->error = "IV mechanism required";
  1087 + return -EINVAL;
1090 1088 }
1091 1089  
1092   - ret = -ENOMEM;
1093   - if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)",
1094   - chainmode, cipher) >= CRYPTO_MAX_ALG_NAME) {
1095   - ti->error = "Chain mode + cipher name is too long";
1096   - goto bad;
  1090 + cipher_api = kmalloc(CRYPTO_MAX_ALG_NAME, GFP_KERNEL);
  1091 + if (!cipher_api)
  1092 + goto bad_mem;
  1093 +
  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 1103 if (IS_ERR(cc->tfm)) {
  1104 + ret = PTR_ERR(cc->tfm);
1101 1105 ti->error = "Error allocating crypto tfm";
1102 1106 goto bad;
1103 1107 }
1104 1108  
1105   - strcpy(cc->cipher, cipher);
1106   - strcpy(cc->chainmode, chainmode);
1107   -
1108   - ret = crypt_set_key(cc, argv[1]);
  1109 + /* Initialize and set key */
  1110 + ret = crypt_set_key(cc, key);
1109 1111 if (ret < 0) {
1110 1112 ti->error = "Error decoding and setting key";
1111 1113 goto bad;
1112 1114 }
1113 1115  
1114   - /*
1115   - * Choose ivmode. Valid modes: "plain", "essiv:<esshash>", "benbi".
1116   - * See comments at iv code
1117   - */
1118   - ret = -EINVAL;
  1116 + /* Initialize IV */
  1117 + cc->iv_size = crypto_ablkcipher_ivsize(cc->tfm);
  1118 + if (cc->iv_size)
  1119 + /* at least a 64 bit sector number should fit in our buffer */
  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 1128 if (ivmode == NULL)
1120 1129 cc->iv_gen_ops = NULL;
1121 1130 else if (strcmp(ivmode, "plain") == 0)
... ... @@ -1129,6 +1138,7 @@
1129 1138 else if (strcmp(ivmode, "null") == 0)
1130 1139 cc->iv_gen_ops = &crypt_iv_null_ops;
1131 1140 else {
  1141 + ret = -EINVAL;
1132 1142 ti->error = "Invalid IV mode";
1133 1143 goto bad;
1134 1144 }
1135 1145  
... ... @@ -1151,20 +1161,45 @@
1151 1161 }
1152 1162 }
1153 1163  
1154   - cc->iv_size = crypto_ablkcipher_ivsize(cc->tfm);
1155   - if (cc->iv_size)
1156   - /* at least a 64 bit sector number should fit in our buffer */
1157   - cc->iv_size = max(cc->iv_size,
1158   - (unsigned int)(sizeof(u64) / sizeof(u8)));
1159   - else {
1160   - if (cc->iv_gen_ops) {
1161   - DMWARN("Selected cipher does not support IVs");
1162   - if (cc->iv_gen_ops->dtr)
1163   - cc->iv_gen_ops->dtr(cc);
1164   - cc->iv_gen_ops = NULL;
1165   - }
  1164 + ret = 0;
  1165 +bad:
  1166 + kfree(cipher_api);
  1167 + return ret;
  1168 +
  1169 +bad_mem:
  1170 + ti->error = "Cannot allocate cipher strings";
  1171 + return -ENOMEM;
  1172 +}
  1173 +
  1174 +/*
  1175 + * Construct an encryption mapping:
  1176 + * <cipher> <key> <iv_offset> <dev_path> <start>
  1177 + */
  1178 +static 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 1203 ret = -ENOMEM;
1169 1204 cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool);
1170 1205 if (!cc->io_pool) {
... ... @@ -1217,17 +1252,6 @@
1217 1252 cc->start = tmpll;
1218 1253  
1219 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 1255 cc->io_queue = create_singlethread_workqueue("kcryptd_io");
1232 1256 if (!cc->io_queue) {
1233 1257 ti->error = "Couldn't create kcryptd io queue";
... ... @@ -1273,7 +1297,7 @@
1273 1297 static int crypt_status(struct dm_target *ti, status_type_t type,
1274 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 1301 unsigned int sz = 0;
1278 1302  
1279 1303 switch (type) {
1280 1304  
... ... @@ -1282,11 +1306,10 @@
1282 1306 break;
1283 1307  
1284 1308 case STATUSTYPE_TABLE:
1285   - if (cc->iv_mode)
1286   - DMEMIT("%s-%s-%s ", cc->cipher, cc->chainmode,
1287   - cc->iv_mode);
  1309 + if (cc->cipher_mode)
  1310 + DMEMIT("%s-%s ", cc->cipher, cc->cipher_mode);
1288 1311 else
1289   - DMEMIT("%s-%s ", cc->cipher, cc->chainmode);
  1312 + DMEMIT("%s ", cc->cipher);
1290 1313  
1291 1314 if (cc->key_size > 0) {
1292 1315 if ((maxlen - sz) < ((cc->key_size << 1) + 1))