iPXE
crypto.h
Go to the documentation of this file.
00001 #ifndef _IPXE_CRYPTO_H
00002 #define _IPXE_CRYPTO_H
00003 
00004 /** @file
00005  *
00006  * Cryptographic API
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdint.h>
00013 #include <stddef.h>
00014 
00015 /** A message digest algorithm */
00016 struct digest_algorithm {
00017         /** Algorithm name */
00018         const char *name;
00019         /** Context size */
00020         size_t ctxsize;
00021         /** Block size */
00022         size_t blocksize;
00023         /** Digest size */
00024         size_t digestsize;
00025         /** Initialise digest
00026          *
00027          * @v ctx               Context
00028          */
00029         void ( * init ) ( void *ctx );
00030         /** Update digest with new data
00031          *
00032          * @v ctx               Context
00033          * @v src               Data to digest
00034          * @v len               Length of data
00035          *
00036          * @v len is not necessarily a multiple of @c blocksize.
00037          */
00038         void ( * update ) ( void *ctx, const void *src, size_t len );
00039         /** Finalise digest
00040          *
00041          * @v ctx               Context
00042          * @v out               Buffer for digest output
00043          */
00044         void ( * final ) ( void *ctx, void *out );
00045 };
00046 
00047 /** A cipher algorithm */
00048 struct cipher_algorithm {
00049         /** Algorithm name */
00050         const char *name;
00051         /** Context size */
00052         size_t ctxsize;
00053         /** Block size */
00054         size_t blocksize;
00055         /** Set key
00056          *
00057          * @v ctx               Context
00058          * @v key               Key
00059          * @v keylen            Key length
00060          * @ret rc              Return status code
00061          */
00062         int ( * setkey ) ( void *ctx, const void *key, size_t keylen );
00063         /** Set initialisation vector
00064          *
00065          * @v ctx               Context
00066          * @v iv                Initialisation vector
00067          */
00068         void ( * setiv ) ( void *ctx, const void *iv );
00069         /** Encrypt data
00070          *
00071          * @v ctx               Context
00072          * @v src               Data to encrypt
00073          * @v dst               Buffer for encrypted data
00074          * @v len               Length of data
00075          *
00076          * @v len is guaranteed to be a multiple of @c blocksize.
00077          */
00078         void ( * encrypt ) ( void *ctx, const void *src, void *dst,
00079                              size_t len );
00080         /** Decrypt data
00081          *
00082          * @v ctx               Context
00083          * @v src               Data to decrypt
00084          * @v dst               Buffer for decrypted data
00085          * @v len               Length of data
00086          *
00087          * @v len is guaranteed to be a multiple of @c blocksize.
00088          */
00089         void ( * decrypt ) ( void *ctx, const void *src, void *dst,
00090                              size_t len );
00091 };
00092 
00093 /** A public key algorithm */
00094 struct pubkey_algorithm {
00095         /** Algorithm name */
00096         const char *name;
00097         /** Context size */
00098         size_t ctxsize;
00099         /** Initialise algorithm
00100          *
00101          * @v ctx               Context
00102          * @v key               Key
00103          * @v key_len           Length of key
00104          * @ret rc              Return status code
00105          */
00106         int ( * init ) ( void *ctx, const void *key, size_t key_len );
00107         /** Calculate maximum output length
00108          *
00109          * @v ctx               Context
00110          * @ret max_len         Maximum output length
00111          */
00112         size_t ( * max_len ) ( void *ctx );
00113         /** Encrypt
00114          *
00115          * @v ctx               Context
00116          * @v plaintext         Plaintext
00117          * @v plaintext_len     Length of plaintext
00118          * @v ciphertext        Ciphertext
00119          * @ret ciphertext_len  Length of ciphertext, or negative error
00120          */
00121         int ( * encrypt ) ( void *ctx, const void *data, size_t len,
00122                             void *out );
00123         /** Decrypt
00124          *
00125          * @v ctx               Context
00126          * @v ciphertext        Ciphertext
00127          * @v ciphertext_len    Ciphertext length
00128          * @v plaintext         Plaintext
00129          * @ret plaintext_len   Plaintext length, or negative error
00130          */
00131         int ( * decrypt ) ( void *ctx, const void *data, size_t len,
00132                             void *out );
00133         /** Sign digest value
00134          *
00135          * @v ctx               Context
00136          * @v digest            Digest algorithm
00137          * @v value             Digest value
00138          * @v signature         Signature
00139          * @ret signature_len   Signature length, or negative error
00140          */
00141         int ( * sign ) ( void *ctx, struct digest_algorithm *digest,
00142                          const void *value, void *signature );
00143         /** Verify signed digest value
00144          *
00145          * @v ctx               Context
00146          * @v digest            Digest algorithm
00147          * @v value             Digest value
00148          * @v signature         Signature
00149          * @v signature_len     Signature length
00150          * @ret rc              Return status code
00151          */
00152         int ( * verify ) ( void *ctx, struct digest_algorithm *digest,
00153                            const void *value, const void *signature,
00154                            size_t signature_len );
00155         /** Finalise algorithm
00156          *
00157          * @v ctx               Context
00158          */
00159         void ( * final ) ( void *ctx );
00160         /** Check that public key matches private key
00161          *
00162          * @v private_key       Private key
00163          * @v private_key_len   Private key length
00164          * @v public_key        Public key
00165          * @v public_key_len    Public key length
00166          * @ret rc              Return status code
00167          */
00168         int ( * match ) ( const void *private_key, size_t private_key_len,
00169                           const void *public_key, size_t public_key_len );
00170 };
00171 
00172 static inline void digest_init ( struct digest_algorithm *digest,
00173                                  void *ctx ) {
00174         digest->init ( ctx );
00175 }
00176 
00177 static inline void digest_update ( struct digest_algorithm *digest,
00178                                    void *ctx, const void *data, size_t len ) {
00179         digest->update ( ctx, data, len );
00180 }
00181 
00182 static inline void digest_final ( struct digest_algorithm *digest,
00183                                   void *ctx, void *out ) {
00184         digest->final ( ctx, out );
00185 }
00186 
00187 static inline int cipher_setkey ( struct cipher_algorithm *cipher,
00188                                   void *ctx, const void *key, size_t keylen ) {
00189         return cipher->setkey ( ctx, key, keylen );
00190 }
00191 
00192 static inline void cipher_setiv ( struct cipher_algorithm *cipher,
00193                                   void *ctx, const void *iv ) {
00194         cipher->setiv ( ctx, iv );
00195 }
00196 
00197 static inline void cipher_encrypt ( struct cipher_algorithm *cipher,
00198                                     void *ctx, const void *src, void *dst,
00199                                     size_t len ) {
00200         cipher->encrypt ( ctx, src, dst, len );
00201 }
00202 #define cipher_encrypt( cipher, ctx, src, dst, len ) do {               \
00203         assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 );        \
00204         cipher_encrypt ( (cipher), (ctx), (src), (dst), (len) );        \
00205         } while ( 0 )
00206 
00207 static inline void cipher_decrypt ( struct cipher_algorithm *cipher,
00208                                     void *ctx, const void *src, void *dst,
00209                                     size_t len ) {
00210         cipher->decrypt ( ctx, src, dst, len );
00211 }
00212 #define cipher_decrypt( cipher, ctx, src, dst, len ) do {               \
00213         assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 );        \
00214         cipher_decrypt ( (cipher), (ctx), (src), (dst), (len) );        \
00215         } while ( 0 )
00216 
00217 static inline int is_stream_cipher ( struct cipher_algorithm *cipher ) {
00218         return ( cipher->blocksize == 1 );
00219 }
00220 
00221 static inline int pubkey_init ( struct pubkey_algorithm *pubkey, void *ctx,
00222                                 const void *key, size_t key_len ) {
00223         return pubkey->init ( ctx, key, key_len );
00224 }
00225 
00226 static inline size_t pubkey_max_len ( struct pubkey_algorithm *pubkey,
00227                                       void *ctx ) {
00228         return pubkey->max_len ( ctx );
00229 }
00230 
00231 static inline int pubkey_encrypt ( struct pubkey_algorithm *pubkey, void *ctx,
00232                                    const void *data, size_t len, void *out ) {
00233         return pubkey->encrypt ( ctx, data, len, out );
00234 }
00235 
00236 static inline int pubkey_decrypt ( struct pubkey_algorithm *pubkey, void *ctx,
00237                                    const void *data, size_t len, void *out ) {
00238         return pubkey->decrypt ( ctx, data, len, out );
00239 }
00240 
00241 static inline int pubkey_sign ( struct pubkey_algorithm *pubkey, void *ctx,
00242                                 struct digest_algorithm *digest,
00243                                 const void *value, void *signature ) {
00244         return pubkey->sign ( ctx, digest, value, signature );
00245 }
00246 
00247 static inline int pubkey_verify ( struct pubkey_algorithm *pubkey, void *ctx,
00248                                   struct digest_algorithm *digest,
00249                                   const void *value, const void *signature,
00250                                   size_t signature_len ) {
00251         return pubkey->verify ( ctx, digest, value, signature, signature_len );
00252 }
00253 
00254 static inline void pubkey_final ( struct pubkey_algorithm *pubkey, void *ctx ) {
00255         pubkey->final ( ctx );
00256 }
00257 
00258 static inline int pubkey_match ( struct pubkey_algorithm *pubkey,
00259                                  const void *private_key,
00260                                  size_t private_key_len, const void *public_key,
00261                                  size_t public_key_len ) {
00262         return pubkey->match ( private_key, private_key_len, public_key,
00263                                public_key_len );
00264 }
00265 
00266 extern struct digest_algorithm digest_null;
00267 extern struct cipher_algorithm cipher_null;
00268 extern struct pubkey_algorithm pubkey_null;
00269 
00270 #endif /* _IPXE_CRYPTO_H */