mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / secur32 / util.c
blobb5cac5b6c063d0d7a4d6e9329579d0960049db94
1 /*
2 * Copyright 2006 Kai Blin
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file contains various helper functions needed for NTLM and maybe others
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "rpc.h"
25 #include "sspi.h"
26 #include "secur32_priv.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(ntlm);
31 static const char client_to_server_sign_constant[] = "session key to client-to-server signing key magic constant";
32 static const char client_to_server_seal_constant[] = "session key to client-to-server sealing key magic constant";
33 static const char server_to_client_sign_constant[] = "session key to server-to-client signing key magic constant";
34 static const char server_to_client_seal_constant[] = "session key to server-to-client sealing key magic constant";
36 typedef struct
38 unsigned int buf[4];
39 unsigned int i[2];
40 unsigned char in[64];
41 unsigned char digest[16];
42 } MD4_CTX;
44 /* And now the same with a different memory layout. */
45 typedef struct
47 unsigned int i[2];
48 unsigned int buf[4];
49 unsigned char in[64];
50 unsigned char digest[16];
51 } MD5_CTX;
53 VOID WINAPI MD4Init( MD4_CTX *ctx );
54 VOID WINAPI MD4Update( MD4_CTX *ctx, const unsigned char *buf, unsigned int len );
55 VOID WINAPI MD4Final( MD4_CTX *ctx );
56 VOID WINAPI MD5Init( MD5_CTX *ctx );
57 VOID WINAPI MD5Update( MD5_CTX *ctx, const unsigned char *buf, unsigned int len );
58 VOID WINAPI MD5Final( MD5_CTX *ctx );
60 SECURITY_STATUS SECUR32_CreateNTLM1SessionKey(PBYTE password, int len, PBYTE session_key)
62 MD4_CTX ctx;
63 BYTE ntlm_hash[16];
65 TRACE("(%p, %p)\n", password, session_key);
67 MD4Init(&ctx);
68 MD4Update(&ctx, password, len);
69 MD4Final(&ctx);
71 memcpy(ntlm_hash, ctx.digest, 0x10);
73 MD4Init(&ctx);
74 MD4Update(&ctx, ntlm_hash, 0x10u);
75 MD4Final(&ctx);
77 memcpy(session_key, ctx.digest, 0x10);
79 return SEC_E_OK;
82 static void SECUR32_CalcNTLM2Subkey(const BYTE *session_key, const char *magic, PBYTE subkey)
84 MD5_CTX ctx;
86 MD5Init(&ctx);
87 MD5Update(&ctx, session_key, 16);
88 MD5Update(&ctx, (const unsigned char*)magic, lstrlenA(magic)+1);
89 MD5Final(&ctx);
90 memcpy(subkey, ctx.digest, 16);
93 /* This assumes we do have a valid NTLM2 user session key */
94 SECURITY_STATUS SECUR32_CreateNTLM2SubKeys(PNegoHelper helper)
96 helper->crypt.ntlm2.send_sign_key = heap_alloc(16);
97 helper->crypt.ntlm2.send_seal_key = heap_alloc(16);
98 helper->crypt.ntlm2.recv_sign_key = heap_alloc(16);
99 helper->crypt.ntlm2.recv_seal_key = heap_alloc(16);
101 if(helper->mode == NTLM_CLIENT)
103 SECUR32_CalcNTLM2Subkey(helper->session_key, client_to_server_sign_constant,
104 helper->crypt.ntlm2.send_sign_key);
105 SECUR32_CalcNTLM2Subkey(helper->session_key, client_to_server_seal_constant,
106 helper->crypt.ntlm2.send_seal_key);
107 SECUR32_CalcNTLM2Subkey(helper->session_key, server_to_client_sign_constant,
108 helper->crypt.ntlm2.recv_sign_key);
109 SECUR32_CalcNTLM2Subkey(helper->session_key, server_to_client_seal_constant,
110 helper->crypt.ntlm2.recv_seal_key);
112 else
114 SECUR32_CalcNTLM2Subkey(helper->session_key, server_to_client_sign_constant,
115 helper->crypt.ntlm2.send_sign_key);
116 SECUR32_CalcNTLM2Subkey(helper->session_key, server_to_client_seal_constant,
117 helper->crypt.ntlm2.send_seal_key);
118 SECUR32_CalcNTLM2Subkey(helper->session_key, client_to_server_sign_constant,
119 helper->crypt.ntlm2.recv_sign_key);
120 SECUR32_CalcNTLM2Subkey(helper->session_key, client_to_server_seal_constant,
121 helper->crypt.ntlm2.recv_seal_key);
124 return SEC_E_OK;
127 arc4_info *SECUR32_arc4Alloc(void)
129 arc4_info *a4i = heap_alloc(sizeof(arc4_info));
130 return a4i;
134 * The arc4 code is based on dlls/advapi32/crypt_arc4.c by Mike McCormack,
135 * which in turn is based on public domain code by Wei Dai
137 void SECUR32_arc4Init(arc4_info *a4i, const BYTE *key, unsigned int keyLen)
139 unsigned int keyIndex = 0, stateIndex = 0;
140 unsigned int i, a;
142 TRACE("(%p, %p, %d)\n", a4i, key, keyLen);
144 a4i->x = a4i->y = 0;
146 for (i=0; i<256; i++)
147 a4i->state[i] = i;
149 for (i=0; i<256; i++)
151 a = a4i->state[i];
152 stateIndex += key[keyIndex] + a;
153 stateIndex &= 0xff;
154 a4i->state[i] = a4i->state[stateIndex];
155 a4i->state[stateIndex] = a;
156 if (++keyIndex >= keyLen)
157 keyIndex = 0;
162 void SECUR32_arc4Process(arc4_info *a4i, BYTE *inoutString, unsigned int length)
164 BYTE *const s=a4i->state;
165 unsigned int x = a4i->x;
166 unsigned int y = a4i->y;
167 unsigned int a, b;
169 while(length--)
171 x = (x+1) & 0xff;
172 a = s[x];
173 y = (y+a) & 0xff;
174 b = s[y];
175 s[x] = b;
176 s[y] = a;
177 *inoutString++ ^= s[(a+b) & 0xff];
180 a4i->x = x;
181 a4i->y = y;
184 void SECUR32_arc4Cleanup(arc4_info *a4i)
186 heap_free(a4i);