Leaked source code of windows server 2003
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.

384 lines
8.4 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: keygen.c
  8. //
  9. // Contents: Key generation unit, with very random numbers
  10. //
  11. //
  12. // History: created, 10 Dec 91, richardw
  13. //
  14. //------------------------------------------------------------------------
  15. #ifndef WIN32_CHICAGO
  16. #include "krbprgma.h"
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <kerbcomm.h>
  21. #include <kerberr.h>
  22. #include <kerbcon.h>
  23. #include <dsysdbg.h>
  24. #else // WIN32_CHICAGO
  25. #include <kerb.hxx>
  26. #include <kerbp.h>
  27. #endif // WIN32_CHICAGO
  28. //+---------------------------------------------------------------------------
  29. //
  30. // Function: KerbRandomFill
  31. //
  32. // Synopsis: Generates random data in the buffer.
  33. //
  34. // Arguments: [pbBuffer] --
  35. // [cbBuffer] --
  36. //
  37. // History: 5-20-93 RichardW Created
  38. //
  39. // Notes:
  40. //
  41. //----------------------------------------------------------------------------
  42. KERBERR NTAPI
  43. KerbRandomFill( PUCHAR pbBuffer,
  44. ULONG cbBuffer)
  45. {
  46. if (!CDGenerateRandomBits(pbBuffer, cbBuffer))
  47. {
  48. return(KRB_ERR_GENERIC);
  49. }
  50. return(KDC_ERR_NONE);
  51. }
  52. //+-----------------------------------------------------------------------
  53. //
  54. // Function: KerbMakeKey, public
  55. //
  56. // Synopsis: Create a random desKey
  57. //
  58. // Effects: fills a desKey with (more or less) cryptographically random
  59. // bytes.
  60. //
  61. // Arguments: [EncryptionType] - Encryption type of key
  62. // [NewKey] -- Key to create
  63. //
  64. // Returns: KDC_ERR_NONE or KRB_ERR_GENERIC
  65. //
  66. //
  67. // History: 10 Dec 91 RichardW Created
  68. //
  69. //------------------------------------------------------------------------
  70. KERBERR NTAPI
  71. KerbMakeKey(
  72. IN ULONG EncryptionType,
  73. OUT PKERB_ENCRYPTION_KEY NewKey
  74. )
  75. {
  76. KERBERR Status = KDC_ERR_NONE;
  77. NTSTATUS NtStatus;
  78. PCRYPTO_SYSTEM CryptoSystem;
  79. NewKey->keyvalue.value = NULL;
  80. //
  81. // Locate the crypto system
  82. //
  83. NtStatus = CDLocateCSystem(
  84. EncryptionType,
  85. &CryptoSystem
  86. );
  87. if (!NT_SUCCESS(NtStatus))
  88. {
  89. Status = KDC_ERR_ETYPE_NOTSUPP;
  90. goto Cleanup;
  91. }
  92. NewKey->keyvalue.value = (PUCHAR) MIDL_user_allocate(CryptoSystem->KeySize);
  93. if (NewKey->keyvalue.value == NULL)
  94. {
  95. Status = KRB_ERR_GENERIC;
  96. goto Cleanup;
  97. }
  98. NtStatus = CryptoSystem->RandomKey(
  99. NULL, // no seed
  100. 0, // no seed length
  101. NewKey->keyvalue.value
  102. );
  103. if (!NT_SUCCESS(NtStatus))
  104. {
  105. Status = KRB_ERR_GENERIC;
  106. goto Cleanup;
  107. }
  108. NewKey->keyvalue.length = CryptoSystem->KeySize;
  109. NewKey->keytype = EncryptionType;
  110. Cleanup:
  111. if (!KERB_SUCCESS(Status) && NewKey->keyvalue.value != NULL)
  112. {
  113. MIDL_user_free(NewKey->keyvalue.value);
  114. NewKey->keyvalue.value = NULL;
  115. }
  116. return(Status);
  117. }
  118. //+-----------------------------------------------------------------------
  119. //
  120. // Function: KerbCreateKeyFromBuffer
  121. //
  122. // Synopsis: Create a KERB_ENCRYPT_KEY from a buffer
  123. //
  124. // Effects:
  125. //
  126. // Arguments: NewKey -- Key to create
  127. // Buffer -- Buffer to create key
  128. // BufferSize - Length of buffer in bytes
  129. //
  130. // Returns: KDC_ERR_NONE or KRB_ERR_GENERIC
  131. //
  132. //
  133. // History: 21-May-1996 Created MikeSw
  134. //
  135. //------------------------------------------------------------------------
  136. KERBERR NTAPI
  137. KerbCreateKeyFromBuffer(
  138. OUT PKERB_ENCRYPTION_KEY NewKey,
  139. IN PUCHAR Buffer,
  140. IN ULONG BufferSize,
  141. IN ULONG EncryptionType
  142. )
  143. {
  144. NewKey->keytype = EncryptionType;
  145. NewKey->keyvalue.length = BufferSize;
  146. NewKey->keyvalue.value = (PUCHAR) Buffer;
  147. return(KDC_ERR_NONE);
  148. }
  149. //+-----------------------------------------------------------------------
  150. //
  151. // Function: KerbDuplicateKey
  152. //
  153. // Synopsis: Duplicates a KERB_ENCRYPT_KEY
  154. //
  155. // Effects: Allocates memory
  156. //
  157. // Arguments: NewKey -- Key to create
  158. // Key - key to duplicate
  159. //
  160. // Returns: KDC_ERR_NONE or KRB_ERR_GENERIC
  161. //
  162. //
  163. // History: 21-May-1996 Created MikeSw
  164. //
  165. //------------------------------------------------------------------------
  166. KERBERR NTAPI
  167. KerbDuplicateKey(
  168. OUT PKERB_ENCRYPTION_KEY NewKey,
  169. IN PKERB_ENCRYPTION_KEY Key
  170. )
  171. {
  172. *NewKey = *Key;
  173. NewKey->keyvalue.value = (PUCHAR) MIDL_user_allocate(Key->keyvalue.length);
  174. if (NewKey->keyvalue.value == NULL)
  175. {
  176. return(KRB_ERR_GENERIC);
  177. }
  178. RtlCopyMemory(
  179. NewKey->keyvalue.value,
  180. Key->keyvalue.value,
  181. Key->keyvalue.length
  182. );
  183. return(KDC_ERR_NONE);
  184. }
  185. //+-------------------------------------------------------------------------
  186. //
  187. // Function: KerbFreeKey
  188. //
  189. // Synopsis: Frees a key created by KerbMakeKey or KerbCreateKeyFromBuffer
  190. //
  191. // Effects:
  192. //
  193. // Arguments: Key - the key to free
  194. //
  195. // Requires:
  196. //
  197. // Returns:
  198. //
  199. // Notes:
  200. //
  201. //
  202. //--------------------------------------------------------------------------
  203. VOID
  204. KerbFreeKey(
  205. IN PKERB_ENCRYPTION_KEY Key
  206. )
  207. {
  208. if (Key->keyvalue.value != NULL)
  209. {
  210. MIDL_user_free(Key->keyvalue.value);
  211. Key->keyvalue.value = NULL;
  212. }
  213. }
  214. //+-------------------------------------------------------------------------
  215. //
  216. // Function: KerbMakeExportableKey
  217. //
  218. // Synopsis: Takes a keytype and makes a new key that uses export-strength
  219. // encryption from the key
  220. //
  221. // Effects:
  222. //
  223. // Arguments:
  224. //
  225. // Requires:
  226. //
  227. // Returns:
  228. //
  229. // Notes:
  230. //
  231. //
  232. //--------------------------------------------------------------------------
  233. KERBERR
  234. KerbMakeExportableKey(
  235. IN ULONG KeyType,
  236. OUT PKERB_ENCRYPTION_KEY NewKey
  237. )
  238. {
  239. KERBERR Status = KDC_ERR_NONE;
  240. NTSTATUS NtStatus;
  241. PCRYPTO_SYSTEM CryptoSystem;
  242. NewKey->keyvalue.value = NULL;
  243. //
  244. // Locate the crypto system
  245. //
  246. NtStatus = CDLocateCSystem(
  247. KeyType,
  248. &CryptoSystem
  249. );
  250. if (!NT_SUCCESS(NtStatus) || (CryptoSystem->ExportableEncryptionType == 0))
  251. {
  252. Status = KDC_ERR_ETYPE_NOTSUPP;
  253. goto Cleanup;
  254. }
  255. NtStatus = CDLocateCSystem(
  256. CryptoSystem->ExportableEncryptionType,
  257. &CryptoSystem
  258. );
  259. if (!NT_SUCCESS(NtStatus))
  260. {
  261. Status = KDC_ERR_ETYPE_NOTSUPP;
  262. goto Cleanup;
  263. }
  264. NewKey->keyvalue.value = (PUCHAR) MIDL_user_allocate(CryptoSystem->KeySize);
  265. if (NewKey->keyvalue.value == NULL)
  266. {
  267. Status = KRB_ERR_GENERIC;
  268. goto Cleanup;
  269. }
  270. NtStatus = CryptoSystem->RandomKey(
  271. NULL, // no seed
  272. 0, // no seed length
  273. NewKey->keyvalue.value
  274. );
  275. if (!NT_SUCCESS(NtStatus))
  276. {
  277. Status = KRB_ERR_GENERIC;
  278. goto Cleanup;
  279. }
  280. NewKey->keyvalue.length = CryptoSystem->KeySize;
  281. NewKey->keytype = CryptoSystem->EncryptionType;
  282. Cleanup:
  283. if (!KERB_SUCCESS(Status) && NewKey->keyvalue.value != NULL)
  284. {
  285. MIDL_user_free(NewKey->keyvalue.value);
  286. NewKey->keyvalue.value = NULL;
  287. }
  288. return(Status);
  289. }
  290. //+-------------------------------------------------------------------------
  291. //
  292. // Function: KerbIsKeyExportable
  293. //
  294. // Synopsis: Checks to see if a key is exportable
  295. //
  296. // Effects:
  297. //
  298. // Arguments:
  299. //
  300. // Requires:
  301. //
  302. // Returns:
  303. //
  304. // Notes:
  305. //
  306. //
  307. //--------------------------------------------------------------------------
  308. BOOLEAN
  309. KerbIsKeyExportable(
  310. IN PKERB_ENCRYPTION_KEY Key
  311. )
  312. {
  313. NTSTATUS NtStatus;
  314. PCRYPTO_SYSTEM CryptoSystem;
  315. //
  316. // Locate the crypto system
  317. //
  318. NtStatus = CDLocateCSystem(
  319. (ULONG) Key->keytype,
  320. &CryptoSystem
  321. );
  322. if (!NT_SUCCESS(NtStatus))
  323. {
  324. return(FALSE);
  325. }
  326. if ((CryptoSystem->Attributes & CSYSTEM_EXPORT_STRENGTH) != 0)
  327. {
  328. return(TRUE);
  329. }
  330. else
  331. {
  332. return(FALSE);
  333. }
  334. }