Source code of Windows XP (NT5)
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.

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