4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
29 * Crypto support, using libpkcs11
31 * Some code copied from the server: libsmb smb_crypt.c
32 * with minor changes, i.e. errno.h return values.
33 * XXX: Later, make the server use these.
36 #include <sys/types.h>
43 #include <security/cryptoki.h>
44 #include <security/pkcs11.h>
45 #include <cryptoutil.h>
47 #include "smb_crypt.h"
50 smb_initlmkey(uchar_t
*keyout
, const uchar_t
*keyin
);
53 * Like libsmb smb_auth_DES,
54 * but use uchar_t, return errno.
57 smb_encrypt_DES(uchar_t
*Result
, int ResultLen
,
58 const uchar_t
*Key
, int KeyLen
,
59 const uchar_t
*Data
, int DataLen
)
62 CK_MECHANISM mechanism
;
63 CK_OBJECT_HANDLE hKey
;
64 CK_SESSION_HANDLE hSession
;
65 CK_ULONG ciphertext_len
;
72 * Calculate proper number of iterations.
73 * Known call cases include:
74 * ResultLen=16, KeyLen=14, DataLen=8
75 * ResultLen=24, KeyLen=21, DataLen=8
76 * ResultLen=16, KeyLen=14, DataLen=16
80 if ((KeyLen
% 7) || (DataLen
% 8))
84 if (ResultLen
< (K
* 8))
88 * Use SUNW convenience function to initialize the cryptoki
89 * library, and open a session with a slot that supports
90 * the mechanism we plan on using.
92 mechanism
.mechanism
= CKM_DES_ECB
;
93 mechanism
.pParameter
= NULL
;
94 mechanism
.ulParameterLen
= 0;
95 rv
= SUNW_C_GetMechSession(mechanism
.mechanism
, &hSession
);
100 for (d
= k
= 0; k
< K
; k
++, d
++) {
101 /* Cycle the input again, as necessary. */
104 smb_initlmkey(des_key
, &Key
[k
* 7]);
105 rv
= SUNW_C_KeyToObject(hSession
, mechanism
.mechanism
,
111 /* Initialize the encryption operation in the session */
112 rv
= C_EncryptInit(hSession
, &mechanism
, hKey
);
119 /* Read in the data and encrypt this portion */
120 rv
= C_EncryptUpdate(hSession
,
121 (CK_BYTE_PTR
)Data
+ (d
* 8), 8,
122 (CK_BYTE_PTR
)Result
+ (k
* 8),
129 (void) C_DestroyObject(hSession
, hKey
);
134 (void) C_DestroyObject(hSession
, hKey
);
136 (void) C_CloseSession(hSession
);
142 * See "Netlogon Credential Computation" section of MS-NRPC document.
143 * Same as in libsmb, but output arg first.
146 smb_initlmkey(uchar_t
*keyout
, const uchar_t
*keyin
)
150 keyout
[0] = keyin
[0] >> 0x01;
151 keyout
[1] = ((keyin
[0] & 0x01) << 6) | (keyin
[1] >> 2);
152 keyout
[2] = ((keyin
[1] & 0x03) << 5) | (keyin
[2] >> 3);
153 keyout
[3] = ((keyin
[2] & 0x07) << 4) | (keyin
[3] >> 4);
154 keyout
[4] = ((keyin
[3] & 0x0f) << 3) | (keyin
[4] >> 5);
155 keyout
[5] = ((keyin
[4] & 0x1f) << 2) | (keyin
[5] >> 6);
156 keyout
[6] = ((keyin
[5] & 0x3f) << 1) | (keyin
[6] >> 7);
157 keyout
[7] = keyin
[6] & 0x7f;
159 for (i
= 0; i
< 8; i
++)
160 keyout
[i
] = (keyout
[i
] << 1) & 0xfe;
167 smb_encrypt_RC4(uchar_t
*Result
, int ResultLen
,
168 const uchar_t
*Key
, int KeyLen
,
169 const uchar_t
*Data
, int DataLen
)
172 CK_MECHANISM mechanism
;
173 CK_OBJECT_HANDLE hKey
;
174 CK_SESSION_HANDLE hSession
;
175 CK_ULONG ciphertext_len
;
179 * Use SUNW convenience function to initialize the cryptoki
180 * library, and open a session with a slot that supports
181 * the mechanism we plan on using.
183 mechanism
.mechanism
= CKM_RC4
;
184 mechanism
.pParameter
= NULL
;
185 mechanism
.ulParameterLen
= 0;
186 rv
= SUNW_C_GetMechSession(mechanism
.mechanism
, &hSession
);
191 rv
= SUNW_C_KeyToObject(hSession
, mechanism
.mechanism
,
196 /* Initialize the encryption operation in the session */
197 rv
= C_EncryptInit(hSession
, &mechanism
, hKey
);
201 ciphertext_len
= ResultLen
;
202 rv
= C_EncryptUpdate(hSession
,
203 (CK_BYTE_PTR
)Data
, DataLen
,
204 (CK_BYTE_PTR
)Result
, &ciphertext_len
);
209 (void) C_DestroyObject(hSession
, hKey
);
211 (void) C_CloseSession(hSession
);
217 * Get some random bytes from /dev/urandom
219 * There may be a preferred way to call this via libpkcs11
220 * XXX: (see: C_GenerateRandom, etc. -- later...)
221 * Just read from /dev/urandom for now.
224 smb_get_urandom(void *data
, size_t dlen
)
228 fd
= open("/dev/urandom", O_RDONLY
);
232 rlen
= read(fd
, data
, dlen
);