Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg

Changed the __driver-gcm-aes-aesni to be a proper aead algorithm.
This required a valid setkey and setauthsize functions to be added and also
some changes to make sure that math context is not corrupted when the alg is
used directly.
Note that the __driver-gcm-aes-aesni should not be used directly by modules
that can use it in interrupt context as we don't have a good fallback mechanism
in this case.

Signed-off-by: Adrian Hoban <adrian.hoban@intel.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Tadeusz Struk and committed by
Herbert Xu
81e397d9 d2e3ae6f

+110 -54
+110 -54
arch/x86/crypto/aesni-intel_glue.c
··· 890 890 return ret; 891 891 } 892 892 893 - static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, 894 - unsigned int key_len) 893 + static int common_rfc4106_set_key(struct crypto_aead *aead, const u8 *key, 894 + unsigned int key_len) 895 895 { 896 896 int ret = 0; 897 - struct crypto_tfm *tfm = crypto_aead_tfm(parent); 898 - struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); 899 - struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); 900 - struct aesni_rfc4106_gcm_ctx *child_ctx = 901 - aesni_rfc4106_gcm_ctx_get(cryptd_child); 897 + struct crypto_tfm *tfm = crypto_aead_tfm(aead); 898 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(aead); 902 899 u8 *new_key_align, *new_key_mem = NULL; 903 900 904 901 if (key_len < 4) { ··· 940 943 goto exit; 941 944 } 942 945 ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len); 943 - memcpy(child_ctx, ctx, sizeof(*ctx)); 944 946 exit: 945 947 kfree(new_key_mem); 946 948 return ret; 947 949 } 948 950 949 - /* This is the Integrity Check Value (aka the authentication tag length and can 950 - * be 8, 12 or 16 bytes long. */ 951 - static int rfc4106_set_authsize(struct crypto_aead *parent, 952 - unsigned int authsize) 951 + static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, 952 + unsigned int key_len) 953 953 { 954 954 struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); 955 - struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); 955 + struct crypto_aead *child = cryptd_aead_child(ctx->cryptd_tfm); 956 + struct aesni_rfc4106_gcm_ctx *c_ctx = aesni_rfc4106_gcm_ctx_get(child); 957 + struct cryptd_aead *cryptd_tfm = ctx->cryptd_tfm; 958 + int ret; 956 959 960 + ret = crypto_aead_setkey(child, key, key_len); 961 + if (!ret) { 962 + memcpy(ctx, c_ctx, sizeof(*ctx)); 963 + ctx->cryptd_tfm = cryptd_tfm; 964 + } 965 + return ret; 966 + } 967 + 968 + static int common_rfc4106_set_authsize(struct crypto_aead *aead, 969 + unsigned int authsize) 970 + { 957 971 switch (authsize) { 958 972 case 8: 959 973 case 12: ··· 973 965 default: 974 966 return -EINVAL; 975 967 } 976 - crypto_aead_crt(parent)->authsize = authsize; 977 - crypto_aead_crt(cryptd_child)->authsize = authsize; 968 + crypto_aead_crt(aead)->authsize = authsize; 978 969 return 0; 979 970 } 980 971 981 - static int rfc4106_encrypt(struct aead_request *req) 972 + /* This is the Integrity Check Value (aka the authentication tag length and can 973 + * be 8, 12 or 16 bytes long. */ 974 + static int rfc4106_set_authsize(struct crypto_aead *parent, 975 + unsigned int authsize) 982 976 { 977 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); 978 + struct crypto_aead *child = cryptd_aead_child(ctx->cryptd_tfm); 983 979 int ret; 984 - struct crypto_aead *tfm = crypto_aead_reqtfm(req); 985 - struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); 986 980 987 - if (!irq_fpu_usable()) { 988 - struct aead_request *cryptd_req = 989 - (struct aead_request *) aead_request_ctx(req); 990 - memcpy(cryptd_req, req, sizeof(*req)); 991 - aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); 992 - return crypto_aead_encrypt(cryptd_req); 993 - } else { 994 - struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); 995 - kernel_fpu_begin(); 996 - ret = cryptd_child->base.crt_aead.encrypt(req); 997 - kernel_fpu_end(); 998 - return ret; 999 - } 1000 - } 1001 - 1002 - static int rfc4106_decrypt(struct aead_request *req) 1003 - { 1004 - int ret; 1005 - struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1006 - struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); 1007 - 1008 - if (!irq_fpu_usable()) { 1009 - struct aead_request *cryptd_req = 1010 - (struct aead_request *) aead_request_ctx(req); 1011 - memcpy(cryptd_req, req, sizeof(*req)); 1012 - aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); 1013 - return crypto_aead_decrypt(cryptd_req); 1014 - } else { 1015 - struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); 1016 - kernel_fpu_begin(); 1017 - ret = cryptd_child->base.crt_aead.decrypt(req); 1018 - kernel_fpu_end(); 1019 - return ret; 1020 - } 981 + ret = crypto_aead_setauthsize(child, authsize); 982 + if (!ret) 983 + crypto_aead_crt(parent)->authsize = authsize; 984 + return ret; 1021 985 } 1022 986 1023 987 static int __driver_rfc4106_encrypt(struct aead_request *req) ··· 1164 1184 kfree(src); 1165 1185 } 1166 1186 return retval; 1187 + } 1188 + 1189 + static int rfc4106_encrypt(struct aead_request *req) 1190 + { 1191 + int ret; 1192 + struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1193 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); 1194 + 1195 + if (!irq_fpu_usable()) { 1196 + struct aead_request *cryptd_req = 1197 + (struct aead_request *) aead_request_ctx(req); 1198 + 1199 + memcpy(cryptd_req, req, sizeof(*req)); 1200 + aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); 1201 + ret = crypto_aead_encrypt(cryptd_req); 1202 + } else { 1203 + kernel_fpu_begin(); 1204 + ret = __driver_rfc4106_encrypt(req); 1205 + kernel_fpu_end(); 1206 + } 1207 + return ret; 1208 + } 1209 + 1210 + static int rfc4106_decrypt(struct aead_request *req) 1211 + { 1212 + int ret; 1213 + struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1214 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); 1215 + 1216 + if (!irq_fpu_usable()) { 1217 + struct aead_request *cryptd_req = 1218 + (struct aead_request *) aead_request_ctx(req); 1219 + 1220 + memcpy(cryptd_req, req, sizeof(*req)); 1221 + aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); 1222 + ret = crypto_aead_decrypt(cryptd_req); 1223 + } else { 1224 + kernel_fpu_begin(); 1225 + ret = __driver_rfc4106_decrypt(req); 1226 + kernel_fpu_end(); 1227 + } 1228 + return ret; 1229 + } 1230 + 1231 + static int helper_rfc4106_encrypt(struct aead_request *req) 1232 + { 1233 + int ret; 1234 + 1235 + if (unlikely(!irq_fpu_usable())) { 1236 + WARN_ONCE(1, "__gcm-aes-aesni alg used in invalid context"); 1237 + ret = -EINVAL; 1238 + } else { 1239 + kernel_fpu_begin(); 1240 + ret = __driver_rfc4106_encrypt(req); 1241 + kernel_fpu_end(); 1242 + } 1243 + return ret; 1244 + } 1245 + 1246 + static int helper_rfc4106_decrypt(struct aead_request *req) 1247 + { 1248 + int ret; 1249 + 1250 + if (unlikely(!irq_fpu_usable())) { 1251 + WARN_ONCE(1, "__gcm-aes-aesni alg used in invalid context"); 1252 + ret = -EINVAL; 1253 + } else { 1254 + kernel_fpu_begin(); 1255 + ret = __driver_rfc4106_decrypt(req); 1256 + kernel_fpu_end(); 1257 + } 1258 + return ret; 1167 1259 } 1168 1260 #endif 1169 1261 ··· 1418 1366 .cra_module = THIS_MODULE, 1419 1367 .cra_u = { 1420 1368 .aead = { 1421 - .encrypt = __driver_rfc4106_encrypt, 1422 - .decrypt = __driver_rfc4106_decrypt, 1369 + .setkey = common_rfc4106_set_key, 1370 + .setauthsize = common_rfc4106_set_authsize, 1371 + .encrypt = helper_rfc4106_encrypt, 1372 + .decrypt = helper_rfc4106_decrypt, 1373 + .ivsize = 8, 1374 + .maxauthsize = 16, 1423 1375 }, 1424 1376 }, 1425 1377 }, {