You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

crypto.h 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #ifndef _IPXE_CRYPTO_H
  2. #define _IPXE_CRYPTO_H
  3. /** @file
  4. *
  5. * Cryptographic API
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  9. #include <stdint.h>
  10. #include <stddef.h>
  11. /** A message digest algorithm */
  12. struct digest_algorithm {
  13. /** Algorithm name */
  14. const char *name;
  15. /** Context size */
  16. size_t ctxsize;
  17. /** Block size */
  18. size_t blocksize;
  19. /** Digest size */
  20. size_t digestsize;
  21. /** Initialise digest
  22. *
  23. * @v ctx Context
  24. */
  25. void ( * init ) ( void *ctx );
  26. /** Update digest with new data
  27. *
  28. * @v ctx Context
  29. * @v src Data to digest
  30. * @v len Length of data
  31. *
  32. * @v len is not necessarily a multiple of @c blocksize.
  33. */
  34. void ( * update ) ( void *ctx, const void *src, size_t len );
  35. /** Finalise digest
  36. *
  37. * @v ctx Context
  38. * @v out Buffer for digest output
  39. */
  40. void ( * final ) ( void *ctx, void *out );
  41. };
  42. /** A cipher algorithm */
  43. struct cipher_algorithm {
  44. /** Algorithm name */
  45. const char *name;
  46. /** Context size */
  47. size_t ctxsize;
  48. /** Block size */
  49. size_t blocksize;
  50. /** Set key
  51. *
  52. * @v ctx Context
  53. * @v key Key
  54. * @v keylen Key length
  55. * @ret rc Return status code
  56. */
  57. int ( * setkey ) ( void *ctx, const void *key, size_t keylen );
  58. /** Set initialisation vector
  59. *
  60. * @v ctx Context
  61. * @v iv Initialisation vector
  62. */
  63. void ( * setiv ) ( void *ctx, const void *iv );
  64. /** Encrypt data
  65. *
  66. * @v ctx Context
  67. * @v src Data to encrypt
  68. * @v dst Buffer for encrypted data
  69. * @v len Length of data
  70. *
  71. * @v len is guaranteed to be a multiple of @c blocksize.
  72. */
  73. void ( * encrypt ) ( void *ctx, const void *src, void *dst,
  74. size_t len );
  75. /** Decrypt data
  76. *
  77. * @v ctx Context
  78. * @v src Data to decrypt
  79. * @v dst Buffer for decrypted data
  80. * @v len Length of data
  81. *
  82. * @v len is guaranteed to be a multiple of @c blocksize.
  83. */
  84. void ( * decrypt ) ( void *ctx, const void *src, void *dst,
  85. size_t len );
  86. };
  87. /** A public key algorithm */
  88. struct pubkey_algorithm {
  89. /** Algorithm name */
  90. const char *name;
  91. /** Context size */
  92. size_t ctxsize;
  93. /** Initialise algorithm
  94. *
  95. * @v ctx Context
  96. * @v key Key
  97. * @v key_len Length of key
  98. * @ret rc Return status code
  99. */
  100. int ( * init ) ( void *ctx, const void *key, size_t key_len );
  101. /** Calculate maximum output length
  102. *
  103. * @v ctx Context
  104. * @ret max_len Maximum output length
  105. */
  106. size_t ( * max_len ) ( void *ctx );
  107. /** Encrypt
  108. *
  109. * @v ctx Context
  110. * @v plaintext Plaintext
  111. * @v plaintext_len Length of plaintext
  112. * @v ciphertext Ciphertext
  113. * @ret ciphertext_len Length of ciphertext, or negative error
  114. */
  115. int ( * encrypt ) ( void *ctx, const void *data, size_t len,
  116. void *out );
  117. /** Decrypt
  118. *
  119. * @v ctx Context
  120. * @v ciphertext Ciphertext
  121. * @v ciphertext_len Ciphertext length
  122. * @v plaintext Plaintext
  123. * @ret plaintext_len Plaintext length, or negative error
  124. */
  125. int ( * decrypt ) ( void *ctx, const void *data, size_t len,
  126. void *out );
  127. /** Sign digest value
  128. *
  129. * @v ctx Context
  130. * @v digest Digest algorithm
  131. * @v value Digest value
  132. * @v signature Signature
  133. * @ret signature_len Signature length, or negative error
  134. */
  135. int ( * sign ) ( void *ctx, struct digest_algorithm *digest,
  136. const void *value, void *signature );
  137. /** Verify signed digest value
  138. *
  139. * @v ctx Context
  140. * @v digest Digest algorithm
  141. * @v value Digest value
  142. * @v signature Signature
  143. * @v signature_len Signature length
  144. * @ret rc Return status code
  145. */
  146. int ( * verify ) ( void *ctx, struct digest_algorithm *digest,
  147. const void *value, const void *signature,
  148. size_t signature_len );
  149. /** Finalise algorithm
  150. *
  151. * @v ctx Context
  152. */
  153. void ( * final ) ( void *ctx );
  154. /** Check that public key matches private key
  155. *
  156. * @v private_key Private key
  157. * @v private_key_len Private key length
  158. * @v public_key Public key
  159. * @v public_key_len Public key length
  160. * @ret rc Return status code
  161. */
  162. int ( * match ) ( const void *private_key, size_t private_key_len,
  163. const void *public_key, size_t public_key_len );
  164. };
  165. static inline void digest_init ( struct digest_algorithm *digest,
  166. void *ctx ) {
  167. digest->init ( ctx );
  168. }
  169. static inline void digest_update ( struct digest_algorithm *digest,
  170. void *ctx, const void *data, size_t len ) {
  171. digest->update ( ctx, data, len );
  172. }
  173. static inline void digest_final ( struct digest_algorithm *digest,
  174. void *ctx, void *out ) {
  175. digest->final ( ctx, out );
  176. }
  177. static inline int cipher_setkey ( struct cipher_algorithm *cipher,
  178. void *ctx, const void *key, size_t keylen ) {
  179. return cipher->setkey ( ctx, key, keylen );
  180. }
  181. static inline void cipher_setiv ( struct cipher_algorithm *cipher,
  182. void *ctx, const void *iv ) {
  183. cipher->setiv ( ctx, iv );
  184. }
  185. static inline void cipher_encrypt ( struct cipher_algorithm *cipher,
  186. void *ctx, const void *src, void *dst,
  187. size_t len ) {
  188. cipher->encrypt ( ctx, src, dst, len );
  189. }
  190. #define cipher_encrypt( cipher, ctx, src, dst, len ) do { \
  191. assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 ); \
  192. cipher_encrypt ( (cipher), (ctx), (src), (dst), (len) ); \
  193. } while ( 0 )
  194. static inline void cipher_decrypt ( struct cipher_algorithm *cipher,
  195. void *ctx, const void *src, void *dst,
  196. size_t len ) {
  197. cipher->decrypt ( ctx, src, dst, len );
  198. }
  199. #define cipher_decrypt( cipher, ctx, src, dst, len ) do { \
  200. assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 ); \
  201. cipher_decrypt ( (cipher), (ctx), (src), (dst), (len) ); \
  202. } while ( 0 )
  203. static inline int is_stream_cipher ( struct cipher_algorithm *cipher ) {
  204. return ( cipher->blocksize == 1 );
  205. }
  206. static inline int pubkey_init ( struct pubkey_algorithm *pubkey, void *ctx,
  207. const void *key, size_t key_len ) {
  208. return pubkey->init ( ctx, key, key_len );
  209. }
  210. static inline size_t pubkey_max_len ( struct pubkey_algorithm *pubkey,
  211. void *ctx ) {
  212. return pubkey->max_len ( ctx );
  213. }
  214. static inline int pubkey_encrypt ( struct pubkey_algorithm *pubkey, void *ctx,
  215. const void *data, size_t len, void *out ) {
  216. return pubkey->encrypt ( ctx, data, len, out );
  217. }
  218. static inline int pubkey_decrypt ( struct pubkey_algorithm *pubkey, void *ctx,
  219. const void *data, size_t len, void *out ) {
  220. return pubkey->decrypt ( ctx, data, len, out );
  221. }
  222. static inline int pubkey_sign ( struct pubkey_algorithm *pubkey, void *ctx,
  223. struct digest_algorithm *digest,
  224. const void *value, void *signature ) {
  225. return pubkey->sign ( ctx, digest, value, signature );
  226. }
  227. static inline int pubkey_verify ( struct pubkey_algorithm *pubkey, void *ctx,
  228. struct digest_algorithm *digest,
  229. const void *value, const void *signature,
  230. size_t signature_len ) {
  231. return pubkey->verify ( ctx, digest, value, signature, signature_len );
  232. }
  233. static inline void pubkey_final ( struct pubkey_algorithm *pubkey, void *ctx ) {
  234. pubkey->final ( ctx );
  235. }
  236. static inline int pubkey_match ( struct pubkey_algorithm *pubkey,
  237. const void *private_key,
  238. size_t private_key_len, const void *public_key,
  239. size_t public_key_len ) {
  240. return pubkey->match ( private_key, private_key_len, public_key,
  241. public_key_len );
  242. }
  243. extern struct digest_algorithm digest_null;
  244. extern struct cipher_algorithm cipher_null;
  245. extern struct pubkey_algorithm pubkey_null;
  246. #endif /* _IPXE_CRYPTO_H */