1/* 2 * Scatterlist Cryptographic API. 3 * 4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 5 * Copyright (c) 2002 David S. Miller (davem@redhat.com) 6 * 7 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> 8 * and Nettle, by Niels M���ler. 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the Free 12 * Software Foundation; either version 2 of the License, or (at your option) 13 * any later version. 14 * 15 */ 16#ifndef _LINUX_CRYPTO_H 17#define _LINUX_CRYPTO_H 18 19#include <linux/module.h> 20#include <linux/kernel.h> 21#include <linux/types.h> 22#include <linux/list.h> 23#include <linux/string.h> 24#include <asm/page.h> 25#include <asm/errno.h> 26 27#define crypto_register_alg crypto_register_alg_rsl 28#define crypto_unregister_alg crypto_unregister_alg_rsl 29#define crypto_alloc_tfm crypto_alloc_tfm_rsl 30#define crypto_free_tfm crypto_free_tfm_rsl 31#define crypto_alg_available crypto_alg_available_rsl 32 33/* 34 * Algorithm masks and types. 35 */ 36#define CRYPTO_ALG_TYPE_MASK 0x000000ff 37#define CRYPTO_ALG_TYPE_CIPHER 0x00000001 38#define CRYPTO_ALG_TYPE_DIGEST 0x00000002 39#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004 40 41/* 42 * Transform masks and values (for crt_flags). 43 */ 44#define CRYPTO_TFM_MODE_MASK 0x000000ff 45#define CRYPTO_TFM_REQ_MASK 0x000fff00 46#define CRYPTO_TFM_RES_MASK 0xfff00000 47 48#define CRYPTO_TFM_MODE_ECB 0x00000001 49#define CRYPTO_TFM_MODE_CBC 0x00000002 50#define CRYPTO_TFM_MODE_CFB 0x00000004 51#define CRYPTO_TFM_MODE_CTR 0x00000008 52 53#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 54#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 55#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 56#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 57#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000 58#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000 59 60/* 61 * Miscellaneous stuff. 62 */ 63#define CRYPTO_UNSPEC 0 64#define CRYPTO_MAX_ALG_NAME 64 65 66struct scatterlist; 67 68/* 69 * Algorithms: modular crypto algorithm implementations, managed 70 * via crypto_register_alg() and crypto_unregister_alg(). 71 */ 72struct cipher_alg { 73 unsigned int cia_min_keysize; 74 unsigned int cia_max_keysize; 75 int (*cia_setkey)(void *ctx, const u8 *key, 76 unsigned int keylen, u32 *flags); 77 void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); 78 void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); 79}; 80 81struct digest_alg { 82 unsigned int dia_digestsize; 83 void (*dia_init)(void *ctx); 84 void (*dia_update)(void *ctx, const u8 *data, unsigned int len); 85 void (*dia_final)(void *ctx, u8 *out); 86 int (*dia_setkey)(void *ctx, const u8 *key, 87 unsigned int keylen, u32 *flags); 88}; 89 90struct compress_alg { 91 int (*coa_init)(void *ctx); 92 void (*coa_exit)(void *ctx); 93 int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen, 94 u8 *dst, unsigned int *dlen); 95 int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen, 96 u8 *dst, unsigned int *dlen); 97}; 98 99#define cra_cipher cra_u.cipher 100#define cra_digest cra_u.digest 101#define cra_compress cra_u.compress 102 103struct crypto_alg { 104 struct list_head cra_list; 105 u32 cra_flags; 106 unsigned int cra_blocksize; 107 unsigned int cra_ctxsize; 108 const char cra_name[CRYPTO_MAX_ALG_NAME]; 109 110 union { 111 struct cipher_alg cipher; 112 struct digest_alg digest; 113 struct compress_alg compress; 114 } cra_u; 115 116 struct module *cra_module; 117}; 118 119/* 120 * Algorithm registration interface. 121 */ 122int crypto_register_alg(struct crypto_alg *alg); 123int crypto_unregister_alg(struct crypto_alg *alg); 124 125/* 126 * Algorithm query interface. 127 */ 128int crypto_alg_available(const char *name, u32 flags); 129 130/* 131 * Transforms: user-instantiated objects which encapsulate algorithms 132 * and core processing logic. Managed via crypto_alloc_tfm() and 133 * crypto_free_tfm(), as well as the various helpers below. 134 */ 135struct crypto_tfm; 136 137struct cipher_tfm { 138 void *cit_iv; 139 unsigned int cit_ivsize; 140 u32 cit_mode; 141 int (*cit_setkey)(struct crypto_tfm *tfm, 142 const u8 *key, unsigned int keylen); 143 int (*cit_encrypt)(struct crypto_tfm *tfm, 144 struct scatterlist *dst, 145 struct scatterlist *src, 146 unsigned int nbytes); 147 int (*cit_encrypt_iv)(struct crypto_tfm *tfm, 148 struct scatterlist *dst, 149 struct scatterlist *src, 150 unsigned int nbytes, u8 *iv); 151 int (*cit_decrypt)(struct crypto_tfm *tfm, 152 struct scatterlist *dst, 153 struct scatterlist *src, 154 unsigned int nbytes); 155 int (*cit_decrypt_iv)(struct crypto_tfm *tfm, 156 struct scatterlist *dst, 157 struct scatterlist *src, 158 unsigned int nbytes, u8 *iv); 159 void (*cit_xor_block)(u8 *dst, const u8 *src); 160}; 161 162struct digest_tfm { 163 void (*dit_init)(struct crypto_tfm *tfm); 164 void (*dit_update)(struct crypto_tfm *tfm, 165 struct scatterlist *sg, unsigned int nsg); 166 void (*dit_final)(struct crypto_tfm *tfm, u8 *out); 167 void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, 168 unsigned int nsg, u8 *out); 169 int (*dit_setkey)(struct crypto_tfm *tfm, 170 const u8 *key, unsigned int keylen); 171#ifdef CONFIG_CRYPTO_HMAC 172 void *dit_hmac_block; 173#endif 174}; 175 176struct compress_tfm { 177 int (*cot_compress)(struct crypto_tfm *tfm, 178 const u8 *src, unsigned int slen, 179 u8 *dst, unsigned int *dlen); 180 int (*cot_decompress)(struct crypto_tfm *tfm, 181 const u8 *src, unsigned int slen, 182 u8 *dst, unsigned int *dlen); 183}; 184 185#define crt_cipher crt_u.cipher 186#define crt_digest crt_u.digest 187#define crt_compress crt_u.compress 188 189struct crypto_tfm { 190 191 u32 crt_flags; 192 193 union { 194 struct cipher_tfm cipher; 195 struct digest_tfm digest; 196 struct compress_tfm compress; 197 } crt_u; 198 199 struct crypto_alg *__crt_alg; 200}; 201 202/* 203 * Transform user interface. 204 */ 205 206/* 207 * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm. 208 * If that fails and the kernel supports dynamically loadable modules, it 209 * will then attempt to load a module of the same name or alias. A refcount 210 * is grabbed on the algorithm which is then associated with the new transform. 211 * 212 * crypto_free_tfm() frees up the transform and any associated resources, 213 * then drops the refcount on the associated algorithm. 214 */ 215struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); 216void crypto_free_tfm(struct crypto_tfm *tfm); 217 218/* 219 * Transform helpers which query the underlying algorithm. 220 */ 221static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm) 222{ 223 return tfm->__crt_alg->cra_name; 224} 225 226static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm) 227{ 228 struct crypto_alg *alg = tfm->__crt_alg; 229 230 if (alg->cra_module) 231 return alg->cra_module->name; 232 else 233 return NULL; 234} 235 236static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm) 237{ 238 return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK; 239} 240 241static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm) 242{ 243 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 244 return tfm->__crt_alg->cra_cipher.cia_min_keysize; 245} 246 247static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm) 248{ 249 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 250 return tfm->__crt_alg->cra_cipher.cia_max_keysize; 251} 252 253static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) 254{ 255 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 256 return tfm->crt_cipher.cit_ivsize; 257} 258 259static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm) 260{ 261 return tfm->__crt_alg->cra_blocksize; 262} 263 264static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) 265{ 266 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 267 return tfm->__crt_alg->cra_digest.dia_digestsize; 268} 269 270/* 271 * API wrappers. 272 */ 273static inline void crypto_digest_init(struct crypto_tfm *tfm) 274{ 275 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 276 tfm->crt_digest.dit_init(tfm); 277} 278 279static inline void crypto_digest_update(struct crypto_tfm *tfm, 280 struct scatterlist *sg, 281 unsigned int nsg) 282{ 283 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 284 tfm->crt_digest.dit_update(tfm, sg, nsg); 285} 286 287static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) 288{ 289 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 290 tfm->crt_digest.dit_final(tfm, out); 291} 292 293static inline void crypto_digest_digest(struct crypto_tfm *tfm, 294 struct scatterlist *sg, 295 unsigned int nsg, u8 *out) 296{ 297 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 298 tfm->crt_digest.dit_digest(tfm, sg, nsg, out); 299} 300 301static inline int crypto_digest_setkey(struct crypto_tfm *tfm, 302 const u8 *key, unsigned int keylen) 303{ 304 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 305 if (tfm->crt_digest.dit_setkey == NULL) 306 return -ENOSYS; 307 return tfm->crt_digest.dit_setkey(tfm, key, keylen); 308} 309 310static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, 311 const u8 *key, unsigned int keylen) 312{ 313 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 314 return tfm->crt_cipher.cit_setkey(tfm, key, keylen); 315} 316 317static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, 318 struct scatterlist *dst, 319 struct scatterlist *src, 320 unsigned int nbytes) 321{ 322 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 323 return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); 324} 325 326static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, 327 struct scatterlist *dst, 328 struct scatterlist *src, 329 unsigned int nbytes, u8 *iv) 330{ 331 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 332 BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); 333 return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv); 334} 335 336static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, 337 struct scatterlist *dst, 338 struct scatterlist *src, 339 unsigned int nbytes) 340{ 341 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 342 return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); 343} 344 345static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, 346 struct scatterlist *dst, 347 struct scatterlist *src, 348 unsigned int nbytes, u8 *iv) 349{ 350 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 351 BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); 352 return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv); 353} 354 355static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, 356 const u8 *src, unsigned int len) 357{ 358 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 359 memcpy(tfm->crt_cipher.cit_iv, src, len); 360} 361 362static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, 363 u8 *dst, unsigned int len) 364{ 365 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); 366 memcpy(dst, tfm->crt_cipher.cit_iv, len); 367} 368 369static inline int crypto_comp_compress(struct crypto_tfm *tfm, 370 const u8 *src, unsigned int slen, 371 u8 *dst, unsigned int *dlen) 372{ 373 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); 374 return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen); 375} 376 377static inline int crypto_comp_decompress(struct crypto_tfm *tfm, 378 const u8 *src, unsigned int slen, 379 u8 *dst, unsigned int *dlen) 380{ 381 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); 382 return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen); 383} 384 385/* 386 * HMAC support. 387 */ 388#ifdef CONFIG_CRYPTO_HMAC 389void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen); 390void crypto_hmac_update(struct crypto_tfm *tfm, 391 struct scatterlist *sg, unsigned int nsg); 392void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, 393 unsigned int *keylen, u8 *out); 394void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, 395 struct scatterlist *sg, unsigned int nsg, u8 *out); 396#endif /* CONFIG_CRYPTO_HMAC */ 397 398#endif /* _LINUX_CRYPTO_H */ 399