home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / crypl200.zip / CRYPTCAP.C < prev    next >
Text File  |  1996-10-05  |  32KB  |  705 lines

  1. /****************************************************************************
  2. *                                                                            *
  3. *                    cryptlib Capability Management Routines                    *
  4. *                        Copyright Peter Gutmann 1992-1996                    *
  5. *                                                                            *
  6. ****************************************************************************/
  7.  
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "crypt.h"
  11.  
  12. /****************************************************************************
  13. *                                                                            *
  14. *                        Capability Management Functions                        *
  15. *                                                                            *
  16. ****************************************************************************/
  17.  
  18. /* The parameters of most encryption algorithms are traditionally specified
  19.    in bytes, so we define a shorter form of the bitsToBytes() macro to allow
  20.    the capability information to be specified in bits */
  21.  
  22. #define bits(x)    bitsToBytes(x)
  23.  
  24. /* The functions used to implement the null encryption routines */
  25.  
  26. int nullSelfTest( void );
  27. int nullInit( CRYPT_INFO *cryptInfo );
  28. int nullInitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  29. int nullEnd( CRYPT_INFO *cryptInfo );
  30. int nullInitKey( CRYPT_INFO *cryptInfo );
  31. int nullInitIV( CRYPT_INFO *cryptInfo );
  32. int nullGetKeysize( CRYPT_INFO *cryptInfo );
  33. int nullGetData( CRYPT_INFO *cryptInfo, void *buffer );
  34. int nullEncrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  35. int nullDecrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  36.  
  37. /* The functions used to implement the DES encryption routines */
  38.  
  39. int desSelfTest( void );
  40. int desInit( CRYPT_INFO *cryptInfo );
  41. int desInitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  42. int desEnd( CRYPT_INFO *cryptInfo );
  43. int desInitKey( CRYPT_INFO *cryptInfo );
  44. int desGetKeysize( CRYPT_INFO *cryptInfo );
  45. int desEncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  46. int desDecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  47. int desEncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  48. int desDecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  49. int desEncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  50. int desDecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  51. int desEncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  52. int desDecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  53. int desEncryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  54. int desDecryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  55.  
  56. /* The functions used to implement the triple DES encryption routines */
  57.  
  58. int des3SelfTest( void );
  59. int des3Init( CRYPT_INFO *cryptInfo );
  60. int des3InitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  61. int des3End( CRYPT_INFO *cryptInfo );
  62. int des3InitKey( CRYPT_INFO *cryptInfo );
  63. int des3GetKeysize( CRYPT_INFO *cryptInfo );
  64. int des3EncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  65. int des3DecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  66. int des3EncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  67. int des3DecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  68. int des3EncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  69. int des3DecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  70. int des3EncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  71. int des3DecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  72. int des3EncryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  73. int des3DecryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  74.  
  75. /* The functions used to implement the IDEA encryption routines */
  76.  
  77. int ideaSelfTest( void );
  78. int ideaInit( CRYPT_INFO *cryptInfo );
  79. int ideaInitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  80. int ideaEnd( CRYPT_INFO *cryptInfo );
  81. int ideaInitKey( CRYPT_INFO *cryptInfo );
  82. int ideaEncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  83. int ideaDecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  84. int ideaEncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  85. int ideaDecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  86. int ideaEncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  87. int ideaDecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  88. int ideaEncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  89. int ideaDecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  90. int ideaEncryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  91. int ideaDecryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  92.  
  93. /* The functions used to implement the MDC/SHS encryption routines */
  94.  
  95. int mdcshsSelfTest( void );
  96. int mdcshsInit( CRYPT_INFO *cryptInfo );
  97. int mdcshsInitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  98. int mdcshsEnd( CRYPT_INFO *cryptInfo );
  99. int mdcshsInitKey( CRYPT_INFO *cryptInfo );
  100. int mdcshsInitIV( CRYPT_INFO *cryptInfo );
  101. int mdcshsEncrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  102. int mdcshsDecrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  103.  
  104. /* The functions used to implement RC2 encryption routines */
  105.  
  106. int rc2SelfTest( void );
  107. int rc2Init( CRYPT_INFO *cryptInfo );
  108. int rc2InitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  109. int rc2End( CRYPT_INFO *cryptInfo );
  110. int rc2InitKey( CRYPT_INFO *cryptInfo );
  111. int rc2EncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  112. int rc2DecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  113. int rc2EncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  114. int rc2DecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  115. int rc2EncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  116. int rc2DecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  117. int rc2EncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  118. int rc2DecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  119. int rc2EncryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  120. int rc2DecryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  121.  
  122. /* The functions used to implement the RC4 encryption routines */
  123.  
  124. int rc4SelfTest( void );
  125. int rc4Init( CRYPT_INFO *cryptInfo );
  126. int rc4InitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  127. int rc4End( CRYPT_INFO *cryptInfo );
  128. int rc4InitKey( CRYPT_INFO *cryptInfo );
  129. int rc4Encrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  130. int rc4Decrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  131.  
  132. /* The functions used to implement RC5 encryption routines */
  133.  
  134. int rc5SelfTest( void );
  135. int rc5Init( CRYPT_INFO *cryptInfo );
  136. int rc5InitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  137. int rc5End( CRYPT_INFO *cryptInfo );
  138. int rc5InitKey( CRYPT_INFO *cryptInfo );
  139. int rc5EncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  140. int rc5DecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  141. int rc5EncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  142. int rc5DecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  143. int rc5EncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  144. int rc5DecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  145. int rc5EncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  146. int rc5DecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  147. int rc5EncryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  148. int rc5DecryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  149.  
  150. /* The functions used to implement the SAFER and SAFER_SK encryption
  151.    routines */
  152.  
  153. int saferSelfTest( void );
  154. int saferInit( CRYPT_INFO *cryptInfo );
  155. int saferInitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  156. int saferEnd( CRYPT_INFO *cryptInfo );
  157. int saferInitKey( CRYPT_INFO *cryptInfo );
  158. int saferGetKeysize( CRYPT_INFO *cryptInfo );
  159. int saferEncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  160. int saferDecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  161. int saferEncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  162. int saferDecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  163. int saferEncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  164. int saferDecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  165. int saferEncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  166. int saferDecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  167. int saferEncryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  168. int saferDecryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  169.  
  170. /* The functions used to implement the Blowfish and Blowfish_SK encryption
  171.    routines */
  172.  
  173. int blowfishSelfTest( void );
  174. int blowfishInit( CRYPT_INFO *cryptInfo );
  175. int blowfishInitEx( CRYPT_INFO *cryptInfo, const void *cryptInfoEx );
  176. int blowfishEnd( CRYPT_INFO *cryptInfo );
  177. int blowfishInitKey( CRYPT_INFO *cryptInfo );
  178. int blowfishGetKeysize( CRYPT_INFO *cryptInfo );
  179. int blowfishEncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  180. int blowfishDecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  181. int blowfishEncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  182. int blowfishDecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  183. int blowfishEncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  184. int blowfishDecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  185. int blowfishEncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  186. int blowfishDecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length );
  187. int blowfishEncryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  188. int blowfishDecryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length );
  189.  
  190. /* The functions used to implement the Diffie-Hellman key exchange routines */
  191.  
  192. int dhSelfTest( void );
  193. int dhInitKey( CRYPT_INFO *cryptInfo );
  194. int dhEncrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  195. int dhDecrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  196.  
  197. /* The functions used to implement the RSA encryption routines */
  198.  
  199. int rsaSelfTest( void );
  200. int rsaInitKey( CRYPT_INFO *cryptInfo );
  201. int rsaEncrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  202. int rsaDecrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  203.  
  204. /* The functions used to implement the DSA encryption routines */
  205.  
  206. int dsaSelfTest( void );
  207. int dsaInitKey( CRYPT_INFO *cryptInfo );
  208. int dsaEncrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  209. int dsaDecrypt( CRYPT_INFO *cryptInfo, void *buffer, int length );
  210.  
  211. /* The functions used to implement the MD2 hash routines */
  212.  
  213. int md2SelfTest( void );
  214. int md2Init( CRYPT_INFO *cryptInfo );
  215. int md2End( CRYPT_INFO *cryptInfo );
  216. int md2GetData( CRYPT_INFO *cryptInfo, void *buffer );
  217. int md2Hash( CRYPT_INFO *cryptInfo, void *buffer, int length );
  218.  
  219. /* The functions used to implement the MD4 hash routines */
  220.  
  221. int md4SelfTest( void );
  222. int md4Init( CRYPT_INFO *cryptInfo );
  223. int md4End( CRYPT_INFO *cryptInfo );
  224. int md4GetData( CRYPT_INFO *cryptInfo, void *buffer );
  225. int md4Hash( CRYPT_INFO *cryptInfo, void *buffer, int length );
  226.  
  227. /* The functions used to implement the MD5 hash routines */
  228.  
  229. int md5SelfTest( void );
  230. int md5Init( CRYPT_INFO *cryptInfo );
  231. int md5End( CRYPT_INFO *cryptInfo );
  232. int md5GetData( CRYPT_INFO *cryptInfo, void *buffer );
  233. int md5Hash( CRYPT_INFO *cryptInfo, void *buffer, int length );
  234.  
  235. /* The functions used to implement the RIPEMD-160 hash routines */
  236.  
  237. int ripemd160SelfTest( void );
  238. int ripemd160Init( CRYPT_INFO *cryptInfo );
  239. int ripemd160End( CRYPT_INFO *cryptInfo );
  240. int ripemd160GetData( CRYPT_INFO *cryptInfo, void *buffer );
  241. int ripemd160Hash( CRYPT_INFO *cryptInfo, void *buffer, int length );
  242.  
  243. /* The functions used to implement the SHA hash routines */
  244.  
  245. int shaSelfTest( void );
  246. int shaInit( CRYPT_INFO *cryptInfo );
  247. int shaEnd( CRYPT_INFO *cryptInfo );
  248. int shaGetData( CRYPT_INFO *cryptInfo, void *buffer );
  249. int shaHash( CRYPT_INFO *cryptInfo, void *buffer, int length );
  250.  
  251. /* The encryption library intrinsic capability list */
  252.  
  253. static CAPABILITY_INFO intrinsicCapabilities[] = {
  254.     /* The no-encryption capability */
  255.     { CRYPT_ALGO_NONE, CRYPT_MODE_NONE, 0, "None", "None", CRYPT_MAX_SPEED,
  256.         0, 0, 0,
  257.         0, 0, 0,
  258.         nullSelfTest, nullInit, nullInitEx, nullEnd, nullInitKey, nullInitIV,
  259.         nullGetKeysize, nullGetData, nullEncrypt, nullDecrypt, CRYPT_ERROR, NULL },
  260.  
  261.     /* The DES capabilities */
  262.     { CRYPT_ALGO_DES, CRYPT_MODE_ECB, bits( 64 ), "DES", "ECB", CRYPT_ERROR,
  263.         bits( 40 ), bits( 64 ), bits( 64 ),
  264.         bits( 0 ), bits( 0 ), bits( 0  ),
  265.         desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL,
  266.         desGetKeysize, NULL, desEncryptECB, desDecryptECB, CRYPT_ERROR, NULL },
  267.     { CRYPT_ALGO_DES, CRYPT_MODE_CBC, bits( 64 ), "DES", "CBC", CRYPT_ERROR,
  268.         bits( 40 ), bits( 64 ), bits( 64 ),
  269.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  270.         desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL,
  271.         desGetKeysize, NULL, desEncryptCBC, desDecryptCBC, CRYPT_ERROR, NULL },
  272.     { CRYPT_ALGO_DES, CRYPT_MODE_CFB, bits( 8 ), "DES", "CFB", CRYPT_ERROR,
  273.         bits( 40 ), bits( 64 ), bits( 64 ),
  274.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  275.         desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL,
  276.         desGetKeysize, NULL, desEncryptCFB, desDecryptCFB, CRYPT_ERROR, NULL },
  277.     { CRYPT_ALGO_DES, CRYPT_MODE_OFB, bits( 8 ), "DES", "OFB", CRYPT_ERROR,
  278.         bits( 40 ), bits( 64 ), bits( 64 ),
  279.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  280.         desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL,
  281.         desGetKeysize, NULL, desEncryptOFB, desDecryptOFB, CRYPT_ERROR, NULL },
  282.     { CRYPT_ALGO_DES, CRYPT_MODE_PCBC, bits( 64 ), "DES", "PCBC", CRYPT_ERROR,
  283.         bits( 40 ), bits( 64 ), bits( 64 ),
  284.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  285.         desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL,
  286.         desGetKeysize, NULL, desEncryptPCBC, desDecryptPCBC, CRYPT_ERROR, NULL },
  287.  
  288.     /* The triple DES capabilities */
  289.     { CRYPT_ALGO_3DES, CRYPT_MODE_ECB, bits( 64 ), "3DES", "ECB", CRYPT_ERROR,
  290.         bits( 40 ), bits( 128 ), bits( 192 ),
  291.         bits( 0 ), bits( 0 ), bits( 0  ),
  292.         des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL,
  293.         des3GetKeysize, NULL, des3EncryptECB, des3DecryptECB, CRYPT_ERROR, NULL },
  294.     { CRYPT_ALGO_3DES, CRYPT_MODE_CBC, bits( 64 ), "3DES", "CBC", CRYPT_ERROR,
  295.         bits( 40 ), bits( 128 ), bits( 192 ),
  296.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  297.         des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL,
  298.         des3GetKeysize, NULL, des3EncryptCBC, des3DecryptCBC, CRYPT_ERROR, NULL },
  299.     { CRYPT_ALGO_3DES, CRYPT_MODE_CFB, bits( 64 ), "3DES", "CFB", CRYPT_ERROR,
  300.         bits( 40 ), bits( 128 ), bits( 192 ),
  301.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  302.         des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL,
  303.         des3GetKeysize, NULL, des3EncryptCFB, des3DecryptCFB, CRYPT_ERROR, NULL },
  304.     { CRYPT_ALGO_3DES, CRYPT_MODE_OFB, bits( 64 ), "3DES", "OFB", CRYPT_ERROR,
  305.         bits( 40 ), bits( 128 ), bits( 192 ),
  306.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  307.         des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL,
  308.         des3GetKeysize, NULL, des3EncryptOFB, des3DecryptOFB, CRYPT_ERROR, NULL },
  309.     { CRYPT_ALGO_3DES, CRYPT_MODE_PCBC, bits( 64 ), "3DES", "PCBC", CRYPT_ERROR,
  310.         bits( 40 ), bits( 128 ), bits( 192 ),
  311.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  312.         des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL,
  313.         des3GetKeysize, NULL, des3EncryptPCBC, des3DecryptPCBC, CRYPT_ERROR, NULL },
  314.  
  315.     /* The IDEA capabilities */
  316. #ifndef NO_PATENT
  317.     { CRYPT_ALGO_IDEA, CRYPT_MODE_ECB, bits( 64 ), "IDEA", "ECB", CRYPT_ERROR,
  318.         bits( 40 ), bits( 128 ), bits( 128 ),
  319.         bits( 0 ), bits( 0 ), bits( 0 ),
  320.         ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL,
  321.         NULL, NULL, ideaEncryptECB, ideaDecryptECB, CRYPT_ERROR, NULL },
  322.     { CRYPT_ALGO_IDEA, CRYPT_MODE_CBC, bits( 64 ), "IDEA", "CBC", CRYPT_ERROR,
  323.         bits( 40 ), bits( 128 ), bits( 128 ),
  324.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  325.         ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL,
  326.         NULL, NULL, ideaEncryptCBC, ideaDecryptCBC, CRYPT_ERROR, NULL },
  327.     { CRYPT_ALGO_IDEA, CRYPT_MODE_CFB, bits( 8 ), "IDEA", "CFB", CRYPT_ERROR,
  328.         bits( 40 ), bits( 128 ), bits( 128 ),
  329.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  330.         ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL,
  331.         NULL, NULL, ideaEncryptCFB, ideaDecryptCFB, CRYPT_ERROR, NULL },
  332.     { CRYPT_ALGO_IDEA, CRYPT_MODE_OFB, bits( 8 ), "IDEA", "OFB", CRYPT_ERROR,
  333.         bits( 40 ), bits( 128 ), bits( 128 ),
  334.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  335.         ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL,
  336.         NULL, NULL, ideaEncryptOFB, ideaDecryptOFB, CRYPT_ERROR, NULL },
  337.     { CRYPT_ALGO_IDEA, CRYPT_MODE_PCBC, bits( 64 ), "IDEA", "PCBC", CRYPT_ERROR,
  338.         bits( 40 ), bits( 128 ), bits( 128 ),
  339.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  340.         ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL,
  341.         NULL, NULL, ideaEncryptPCBC, ideaDecryptPCBC, CRYPT_ERROR, NULL },
  342. #endif /* NO_PATENT */
  343.  
  344.     /* The RC2 capabilities */
  345.     { CRYPT_ALGO_RC2, CRYPT_MODE_ECB, bits( 64 ), "RC2", "ECB", CRYPT_ERROR,
  346.         bits( 40 ), bits( 128 ), bits( 1024 ),
  347.         bits( 0 ), bits( 0 ), bits( 0 ),
  348.         rc2SelfTest, rc2Init, rc2InitEx, rc2End, rc2InitKey, NULL,
  349.         NULL, NULL, rc2EncryptECB, rc2DecryptECB, CRYPT_ERROR, NULL },
  350.     { CRYPT_ALGO_RC2, CRYPT_MODE_CBC, bits( 64 ), "RC2", "CBC", CRYPT_ERROR,
  351.         bits( 40 ), bits( 128 ), bits( 1024 ),
  352.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  353.         rc2SelfTest, rc2Init, rc2InitEx, rc2End, rc2InitKey, NULL,
  354.         NULL, NULL, rc2EncryptCBC, rc2DecryptCBC, CRYPT_ERROR, NULL },
  355.     { CRYPT_ALGO_RC2, CRYPT_MODE_CFB, bits( 8 ), "RC2", "CFB", CRYPT_ERROR,
  356.         bits( 40 ), bits( 128 ), bits( 1024 ),
  357.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  358.         rc2SelfTest, rc2Init, rc2InitEx, rc2End, rc2InitKey, NULL,
  359.         NULL, NULL, rc2EncryptCFB, rc2DecryptCFB, CRYPT_ERROR, NULL },
  360.     { CRYPT_ALGO_RC2, CRYPT_MODE_OFB, bits( 8 ), "RC2", "OFB", CRYPT_ERROR,
  361.         bits( 40 ), bits( 128 ), bits( 1024 ),
  362.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  363.         rc2SelfTest, rc2Init, rc2InitEx, rc2End, rc2InitKey, NULL,
  364.         NULL, NULL, rc2EncryptOFB, rc2DecryptOFB, CRYPT_ERROR, NULL },
  365.     { CRYPT_ALGO_RC2, CRYPT_MODE_PCBC, bits( 64 ), "RC2", "PCBC", CRYPT_ERROR,
  366.         bits( 40 ), bits( 128 ), bits( 1024 ),
  367.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  368.         rc2SelfTest, rc2Init, rc2InitEx, rc2End, rc2InitKey, NULL,
  369.         NULL, NULL, rc2EncryptPCBC, rc2DecryptPCBC, CRYPT_ERROR, NULL },
  370.  
  371.     /* The RC4 capabilities */
  372.     { CRYPT_ALGO_RC4, CRYPT_MODE_STREAM, bits( 8 ), "RC4", "Stream", CRYPT_ERROR,
  373.         bits( 40 ), bits( 128 ), 256,
  374.         bits( 0 ), bits( 0 ), bits( 0 ),
  375.         rc4SelfTest, rc4Init, rc4InitEx, rc4End, rc4InitKey, NULL,
  376.         NULL, NULL, rc4Encrypt, rc4Decrypt, CRYPT_ERROR, NULL },
  377.  
  378.     /* The RC5 capabilities */
  379. #ifndef NO_PATENT
  380.     { CRYPT_ALGO_RC5, CRYPT_MODE_ECB, bits( 64 ), "RC5", "ECB", CRYPT_ERROR,
  381.         bits( 40 ), bits( 128 ), bits( 832 ),
  382.         bits( 0 ), bits( 0 ), bits( 0 ),
  383.         rc5SelfTest, rc5Init, rc5InitEx, rc5End, rc5InitKey, NULL,
  384.         NULL, NULL, rc5EncryptECB, rc5DecryptECB, CRYPT_ERROR, NULL },
  385.     { CRYPT_ALGO_RC5, CRYPT_MODE_CBC, bits( 64 ), "RC5", "CBC", CRYPT_ERROR,
  386.         bits( 40 ), bits( 128 ), bits( 832 ),
  387.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  388.         rc5SelfTest, rc5Init, rc5InitEx, rc5End, rc5InitKey, NULL,
  389.         NULL, NULL, rc5EncryptCBC, rc5DecryptCBC, CRYPT_ERROR, NULL },
  390.     { CRYPT_ALGO_RC5, CRYPT_MODE_CFB, bits( 8 ), "RC5", "CFB", CRYPT_ERROR,
  391.         bits( 40 ), bits( 128 ), bits( 832 ),
  392.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  393.         rc5SelfTest, rc5Init, rc5InitEx, rc5End, rc5InitKey, NULL,
  394.         NULL, NULL, rc5EncryptCFB, rc5DecryptCFB, CRYPT_ERROR, NULL },
  395.     { CRYPT_ALGO_RC5, CRYPT_MODE_OFB, bits( 8 ), "RC5", "OFB", CRYPT_ERROR,
  396.         bits( 40 ), bits( 128 ), bits( 832 ),
  397.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  398.         rc5SelfTest, rc5Init, rc5InitEx, rc5End, rc5InitKey, NULL,
  399.         NULL, NULL, rc5EncryptOFB, rc5DecryptOFB, CRYPT_ERROR, NULL },
  400.     { CRYPT_ALGO_RC5, CRYPT_MODE_PCBC, bits( 64 ), "RC5", "PCBC", CRYPT_ERROR,
  401.         bits( 40 ), bits( 128 ), bits( 832 ),
  402.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  403.         rc5SelfTest, rc5Init, rc5InitEx, rc5End, rc5InitKey, NULL,
  404.         NULL, NULL, rc5EncryptPCBC, rc5DecryptPCBC, CRYPT_ERROR, NULL },
  405. #endif /* NO_PATENT */
  406.  
  407.     /* The MDC/SHS capabilities */
  408.     { CRYPT_ALGO_MDCSHS, CRYPT_MODE_CFB, bits( 8 ), "MDC/SHS", "CFB", CRYPT_ERROR,
  409.         bits( 40 ), bits( 512 ), CRYPT_MAX_KEYSIZE,
  410.         bits( 32 ), bits( 64 ), CRYPT_MAX_IVSIZE,
  411.         mdcshsSelfTest, mdcshsInit, mdcshsInitEx, mdcshsEnd,
  412.         mdcshsInitKey, mdcshsInitIV, NULL, NULL, mdcshsEncrypt, mdcshsDecrypt,
  413.         CRYPT_ERROR, NULL },
  414.  
  415.     /* The SAFER capabilities */
  416.     { CRYPT_ALGO_SAFER, CRYPT_MODE_ECB, bits( 64 ), "SAFER", "ECB", CRYPT_ERROR,
  417.         bits( 40 ), bits( 64 ), bits( 128 ),
  418.         bits( 0 ), bits( 0 ), bits( 0 ),
  419.         saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL,
  420.         saferGetKeysize, NULL, saferEncryptECB, saferDecryptECB, CRYPT_ERROR, NULL },
  421.     { CRYPT_ALGO_SAFER, CRYPT_MODE_CBC, bits( 64 ), "SAFER", "CBC", CRYPT_ERROR,
  422.         bits( 40 ), bits( 64 ), bits( 128 ),
  423.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  424.         saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL,
  425.         saferGetKeysize, NULL, saferEncryptCBC, saferDecryptCBC, CRYPT_ERROR, NULL },
  426.     { CRYPT_ALGO_SAFER, CRYPT_MODE_CFB, bits( 8 ), "SAFER", "CFB", CRYPT_ERROR,
  427.         bits( 40 ), bits( 64 ), bits( 128 ),
  428.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  429.         saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL,
  430.         saferGetKeysize, NULL, saferEncryptCFB, saferDecryptCFB, CRYPT_ERROR, NULL },
  431.     { CRYPT_ALGO_SAFER, CRYPT_MODE_OFB, bits( 8 ), "SAFER", "OFB", CRYPT_ERROR,
  432.         bits( 40 ), bits( 64 ), bits( 128 ),
  433.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  434.         saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL,
  435.         saferGetKeysize, NULL, saferEncryptOFB, saferDecryptOFB, CRYPT_ERROR, NULL },
  436.     { CRYPT_ALGO_SAFER, CRYPT_MODE_PCBC, bits( 64 ), "SAFER", "PCBC", CRYPT_ERROR,
  437.         bits( 40 ), bits( 64 ), bits( 128 ),
  438.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  439.         saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL,
  440.         saferGetKeysize, NULL, saferEncryptPCBC, saferDecryptPCBC, CRYPT_ERROR, NULL },
  441.  
  442.     /* The Blowfish capabilities */
  443.     { CRYPT_ALGO_BLOWFISH, CRYPT_MODE_ECB, bits( 64 ), "Blowfish", "ECB", CRYPT_ERROR,
  444.         bits( 40 ), bits( 128 ), CRYPT_MAX_KEYSIZE,
  445.         bits( 0 ), bits( 0 ), bits( 0 ),
  446.         blowfishSelfTest, blowfishInit, blowfishInitEx, blowfishEnd, blowfishInitKey, NULL,
  447.         blowfishGetKeysize, NULL, blowfishEncryptECB, blowfishDecryptECB, CRYPT_ERROR, NULL },
  448.     { CRYPT_ALGO_BLOWFISH, CRYPT_MODE_CBC, bits( 64 ), "Blowfish", "CBC", CRYPT_ERROR,
  449.         bits( 40 ), bits( 128 ), CRYPT_MAX_KEYSIZE,
  450.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  451.         blowfishSelfTest, blowfishInit, blowfishInitEx, blowfishEnd, blowfishInitKey, NULL,
  452.         blowfishGetKeysize, NULL, blowfishEncryptCBC, blowfishDecryptCBC, CRYPT_ERROR, NULL },
  453.     { CRYPT_ALGO_BLOWFISH, CRYPT_MODE_CFB, bits( 8 ), "Blowfish", "CFB", CRYPT_ERROR,
  454.         bits( 40 ), bits( 128 ), CRYPT_MAX_KEYSIZE,
  455.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  456.         blowfishSelfTest, blowfishInit, blowfishInitEx, blowfishEnd, blowfishInitKey, NULL,
  457.         blowfishGetKeysize, NULL, blowfishEncryptCFB, blowfishDecryptCFB, CRYPT_ERROR, NULL },
  458.     { CRYPT_ALGO_BLOWFISH, CRYPT_MODE_OFB, bits( 8 ), "Blowfish", "OFB", CRYPT_ERROR,
  459.         bits( 40 ), bits( 128 ), CRYPT_MAX_KEYSIZE,
  460.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  461.         blowfishSelfTest, blowfishInit, blowfishInitEx, blowfishEnd, blowfishInitKey, NULL,
  462.         blowfishGetKeysize, NULL, blowfishEncryptOFB, blowfishDecryptOFB, CRYPT_ERROR, NULL },
  463.     { CRYPT_ALGO_BLOWFISH, CRYPT_MODE_PCBC, bits( 64 ), "Blowfish", "PCBC", CRYPT_ERROR,
  464.         bits( 40 ), bits( 128 ), CRYPT_MAX_KEYSIZE,
  465.         bits( 32 ), CRYPT_MAX_IVSIZE, CRYPT_MAX_IVSIZE,
  466.         blowfishSelfTest, blowfishInit, blowfishInitEx, blowfishEnd, blowfishInitKey, NULL,
  467.         blowfishGetKeysize, NULL, blowfishEncryptPCBC, blowfishDecryptPCBC, CRYPT_ERROR, NULL },
  468.  
  469.     /* The MD2 capabilities */
  470.     { CRYPT_ALGO_MD2, CRYPT_MODE_NONE, bits( 128 ), "MD2",
  471.         "Hash algorithm", CRYPT_ERROR,
  472.         bits( 0 ), bits( 0 ), bits( 0 ),
  473.         bits( 0 ), bits( 0 ), bits( 0 ),
  474.         md2SelfTest, md2Init, NULL, md2End,
  475.         NULL, NULL, NULL, md2GetData, md2Hash, md2Hash,
  476.         CRYPT_ERROR, NULL },
  477.  
  478.     /* The MD4 capabilities */
  479.     { CRYPT_ALGO_MD4, CRYPT_MODE_NONE, bits( 128 ), "MD4",
  480.         "Hash algorithm", CRYPT_ERROR,
  481.         bits( 0 ), bits( 0 ), bits( 0 ),
  482.         bits( 0 ), bits( 0 ), bits( 0 ),
  483.         md4SelfTest, md4Init, NULL, md4End,
  484.         NULL, NULL, NULL, md4GetData, md4Hash, md4Hash,
  485.         CRYPT_ERROR, NULL },
  486.  
  487.     /* The MD5 capabilities */
  488.     { CRYPT_ALGO_MD5, CRYPT_MODE_NONE, bits( 128 ), "MD5",
  489.         "Hash algorithm", CRYPT_ERROR,
  490.         bits( 0 ), bits( 0 ), bits( 0 ),
  491.         bits( 0 ), bits( 0 ), bits( 0 ),
  492.         md5SelfTest, md5Init, NULL, md5End,
  493.         NULL, NULL, NULL, md5GetData, md5Hash, md5Hash,
  494.         CRYPT_ERROR, NULL },
  495.  
  496.     /* The RIPEMD-160 capabilities */
  497.     { CRYPT_ALGO_RIPEMD160, CRYPT_MODE_NONE, bits( 160 ),
  498.         "RIPEMD-160", "Hash algorithm", CRYPT_ERROR,
  499.         bits( 0 ), bits( 0 ), bits( 0 ),
  500.         bits( 0 ), bits( 0 ), bits( 0 ),
  501.         ripemd160SelfTest, ripemd160Init, NULL, ripemd160End,
  502.         NULL, NULL, NULL, ripemd160GetData, ripemd160Hash, ripemd160Hash,
  503.         CRYPT_ERROR, NULL },
  504.  
  505.     /* The SHA capabilities */
  506.     { CRYPT_ALGO_SHA, CRYPT_MODE_NONE, bits( 160 ), "SHA",
  507.         "Hash algorithm", CRYPT_ERROR,
  508.         bits( 0 ), bits( 0 ), bits( 0 ),
  509.         bits( 0 ), bits( 0 ), bits( 0 ),
  510.         shaSelfTest, shaInit, NULL, shaEnd,
  511.         NULL, NULL, NULL, shaGetData, shaHash, shaHash,
  512.         CRYPT_ERROR, NULL },
  513.  
  514.     /* The Diffie-Hellman capabilities */
  515.     { CRYPT_ALGO_DH, CRYPT_MODE_PKC, bits( 0 ), "Diffie-Hellman",
  516.         "Key exchange algorithm", CRYPT_ERROR,
  517.         bits( 512 ), bits( 1024 ), bits( 4096 ),
  518.         bits( 0 ), bits( 0 ), bits( 0 ),
  519.         dhSelfTest, NULL, NULL, NULL, dhInitKey, NULL,
  520.         NULL, NULL, dhEncrypt, dhDecrypt, CRYPT_ERROR, NULL },
  521.  
  522.     /* The RSA capabilities */
  523.     { CRYPT_ALGO_RSA, CRYPT_MODE_PKC, bits( 0 ), "RSA",
  524.         "Public-key algorithm", CRYPT_ERROR,
  525.         bits( 512 ), bits( 1024 ), bits( 4096 ),
  526.         bits( 0 ), bits( 0 ), bits( 0 ),
  527.         rsaSelfTest, NULL, NULL, NULL, rsaInitKey, NULL,
  528.         NULL, NULL, rsaEncrypt, rsaDecrypt, CRYPT_ERROR, NULL },
  529.  
  530.     /* The DSA capabilities */
  531.     { CRYPT_ALGO_DSA, CRYPT_MODE_PKC, bits( 0 ), "DSA",
  532.         "Public-key algorithm", CRYPT_ERROR,
  533.         bits( 512 ), bits( 1024 ), bits( 4096 ),
  534.         bits( 0 ), bits( 0 ), bits( 0 ),
  535.         dsaSelfTest, NULL, NULL, NULL, dsaInitKey, NULL,
  536.         NULL, NULL, dsaEncrypt, dsaDecrypt, CRYPT_ERROR, NULL },
  537.  
  538.     /* The end-of-list marker */
  539.     { CRYPT_ALGO_NONE, CRYPT_MODE_NONE, CRYPT_ERROR, "", "", 0,
  540.         0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL,
  541.         NULL, NULL, NULL, NULL, NULL, NULL, CRYPT_ERROR, NULL }
  542.     };
  543.  
  544. /* The list of crypt library capability records.  Even if initCapabilities()
  545.    is never called we still have a minimum non-encryption method available */
  546.  
  547. static CAPABILITY_INFO *capabilityListHead = NULL;
  548. static CAPABILITY_INFO *capabilityListTail = intrinsicCapabilities;
  549. static CAPABILITY_INFO *intrinsicCapabilityListEnd = NULL;
  550.  
  551. /* Query whether the capability list has been initialised */
  552.  
  553. BOOLEAN queryCapabilitiesInited( void )
  554.     {
  555.     return( ( capabilityListHead != NULL ) ? TRUE : FALSE );
  556.     }
  557.  
  558. /* Free the capability list */
  559.  
  560. void freeCapabilityList( void )
  561.     {
  562.     CAPABILITY_INFO *capabilityListPtr = intrinsicCapabilityListEnd;
  563.     void *capabilityToFree;
  564.  
  565.     /* Mark the list as being empty */
  566.     intrinsicCapabilityListEnd = NULL;
  567.  
  568.     /* Free the capability record list list */
  569.     while( capabilityListPtr != NULL )
  570.         {
  571.         capabilityToFree = capabilityListPtr;
  572.         capabilityListPtr = capabilityListPtr->next;
  573.         cleanFree( &capabilityToFree, sizeof( CAPABILITY_INFO ) );
  574.         }
  575.     }
  576.  
  577. /* Initialise the intrinsic encryption library capability list */
  578.  
  579. int initCapabilities( void )
  580.     {
  581.     CAPABILITY_INFO *capabilityInfoPtr;
  582.     CRYPT_ALGO cryptAlgo = CRYPT_ERROR;
  583.     int i;
  584.  
  585.     /* Add the built-in encryption capabilities */
  586.     for( i = 0; intrinsicCapabilities[ i + 1 ].blockSize != CRYPT_ERROR; i++ )
  587.         intrinsicCapabilities[ i ].next = &intrinsicCapabilities[ i + 1 ];
  588.     capabilityListHead = intrinsicCapabilities;
  589.     capabilityListTail = &intrinsicCapabilities[ i ];
  590.  
  591.     /* Perform the self-test for each encryption algorithm */
  592.     for( capabilityInfoPtr = capabilityListHead;
  593.          capabilityInfoPtr != NULL;
  594.          capabilityInfoPtr = capabilityInfoPtr->next )
  595.         {
  596.         CAPABILITY_INFO *capabilitySelfTestPtr;
  597.         int status;
  598.  
  599.         /* If we've already encountered this algorithm, don't try the
  600.            self-test again */
  601.         if( capabilityInfoPtr->cryptAlgo == cryptAlgo )
  602.             continue;
  603.         cryptAlgo = capabilityInfoPtr->cryptAlgo;
  604.  
  605.         /* Perform the self-test for this algorithm type */
  606.         status = capabilityInfoPtr->selfTestFunction();
  607.  
  608.         /* Set the test status for each capability using this algorithm */
  609.         for( capabilitySelfTestPtr = capabilityInfoPtr;
  610.              capabilitySelfTestPtr != NULL;
  611.              capabilitySelfTestPtr = capabilitySelfTestPtr->next )
  612.             if( capabilitySelfTestPtr->cryptAlgo == capabilityInfoPtr->cryptAlgo )
  613.                 capabilitySelfTestPtr->selfTestStatus = status;
  614.         }
  615.  
  616.     return( CRYPT_OK );
  617.     }
  618.  
  619. #if 0
  620.  
  621. /* Add a capability record to the library */
  622.  
  623. int addCapability( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode, int blockSize,
  624.                    char *algoName, char *modeName, int speed, int minKeySize,
  625.                    int keySize, int maxKeySize )
  626.     {
  627.     CAPABILITY_INFO *newElement;
  628.  
  629.     /* Check the passed-in parameters */
  630.     if( cryptAlgo < CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST )
  631.         return( CRYPT_BADPARM1 );
  632.     if( cryptMode < CRYPT_MODE_NONE || cryptMode >= CRYPT_MODE_LAST )
  633.         return( CRYPT_BADPARM2 );
  634.     if( blockSize < 0 )
  635.         return( CRYPT_BADPARM3 );
  636.     if( algoName == NULL )
  637.         return( CRYPT_BADPARM4 );
  638.     if( modeName == NULL )
  639.         return( CRYPT_BADPARM5 );
  640.     if( ( speed != CRYPT_ERROR && speed < 0 ) || speed > CRYPT_MAX_SPEED )
  641.         return( CRYPT_BADPARM6 );
  642.     if( minKeySize < 0 )
  643.         return( CRYPT_BADPARM7 );
  644.     if( keySize < minKeySize )
  645.         return( CRYPT_BADPARM8 );
  646.     if( maxKeySize < keySize )
  647.         return( CRYPT_BADPARM9 );
  648.  
  649.     /* Allocate memory for the new capability and its associated message */
  650.     if( ( newElement = ( CAPABILITY_INFO * ) malloc( sizeof( CAPABILITY_INFO ) ) ) == NULL )
  651.         return( CRYPT_NOMEM );
  652.     memset( newElement, 0, sizeof( CAPABILITY_INFO ) );
  653.     if( ( newElement->algoName = ( char * ) malloc( strlen( algoName ) + 1 ) ) == NULL )
  654.         {
  655.         free( newElement );
  656.         return( CRYPT_NOMEM );
  657.         }
  658.     if( ( newElement->modeName = ( char * ) malloc( strlen( modeName ) + 1 ) ) == NULL )
  659.         {
  660.         free( newElement->algoName );
  661.         free( newElement );
  662.         return( CRYPT_NOMEM );
  663.         }
  664.  
  665.     /* Copy the information across */
  666.     newElement->cryptAlgo = cryptAlgo;
  667.     newElement->cryptMode = cryptMode;
  668.     newElement->blockSize = blockSize;
  669.     strcpy( newElement->algoName, algoName );
  670.     strcpy( newElement->modeName, modeName );
  671.     newElement->minKeySize = minKeySize;
  672.     newElement->keySize = keySize;
  673.     newElement->maxKeySize = maxKeySize;
  674.     newElement->next = NULL;
  675.  
  676.     /* Link it into the list */
  677.     if( capabilityListHead == NULL )
  678.         capabilityListHead = newElement;
  679.     else
  680.         capabilityListTail->next = newElement;
  681.     capabilityListTail = newElement;
  682.  
  683.     return( CRYPT_OK );
  684.     }
  685. #endif /* 0 */
  686.  
  687. /* Find the capability record for a given encryption algorithm */
  688.  
  689. CAPABILITY_INFO *findCapabilityInfo( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode )
  690.     {
  691.     CAPABILITY_INFO *capabilityInfoPtr;
  692.  
  693.     /* Try and find information on the required algorithm */
  694.     for( capabilityInfoPtr = capabilityListHead;
  695.          capabilityInfoPtr != NULL;
  696.          capabilityInfoPtr = capabilityInfoPtr->next )
  697.         if( capabilityInfoPtr->cryptAlgo == cryptAlgo &&
  698.             ( capabilityInfoPtr->cryptMode == cryptMode ||
  699.               cryptMode == CRYPT_MODE_NONE ) )
  700.             return( capabilityInfoPtr );
  701.  
  702.     /* Nothing available */
  703.     return( NULL );
  704.     }
  705.