1 /* $NetBSD: crypto.c,v 1.1.1.1 2011/04/13 18:14:47 elric Exp $ */
4 * Copyright (c) 2010 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the Institute nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 static uint8_t zeros
[4];
43 _netlogon_encode_sequence_number(uint64_t SequenceNumber
, uint8_t *p
,
46 uint32_t LowPart
, HighPart
;
48 LowPart
= (SequenceNumber
>> 0 ) & 0xFFFFFFFF;
49 HighPart
= (SequenceNumber
>> 32) & 0xFFFFFFFF;
51 _gss_mg_encode_be_uint32(LowPart
, &p
[0]);
52 _gss_mg_encode_be_uint32(HighPart
, &p
[4]);
59 _netlogon_decode_sequence_number(void *ptr
, uint64_t *n
,
63 uint32_t LowPart
, HighPart
;
66 gotInitiatorFlag
= (p
[4] & 0x80) != 0;
67 if (gotInitiatorFlag
!= initiatorFlag
)
70 p
[4] &= 0x7F; /* clear initiator bit */
72 _gss_mg_decode_be_uint32(&p
[0], &LowPart
);
73 _gss_mg_decode_be_uint32(&p
[4], &HighPart
);
75 *n
= (LowPart
<< 0) | ((uint64_t)HighPart
<< 32);
81 _netlogon_checksum_length(NL_AUTH_SIGNATURE
*sig
)
84 return (sig
->SignatureAlgorithm
== NL_SIGN_ALG_SHA256
) ? 32 : 8;
86 /* Owing to a bug in Windows it always uses the old value */
92 _netlogon_signature_length(uint16_t alg
, int conf_req_flag
)
94 return NL_AUTH_SIGNATURE_COMMON_LENGTH
+
95 (alg
== NL_SIGN_ALG_SHA256
? 32 : 8) +
96 (conf_req_flag
? 8 : 0);
99 static inline uint8_t *
100 _netlogon_confounder(NL_AUTH_SIGNATURE
*sig
)
102 size_t cksumlen
= _netlogon_checksum_length(sig
);
104 return &sig
->Checksum
[cksumlen
];
108 _netlogon_encode_NL_AUTH_SIGNATURE(NL_AUTH_SIGNATURE
*sig
,
109 uint8_t *p
, size_t len
)
111 *p
++ = (sig
->SignatureAlgorithm
>> 0) & 0xFF;
112 *p
++ = (sig
->SignatureAlgorithm
>> 8) & 0xFF;
113 *p
++ = (sig
->SealAlgorithm
>> 0) & 0xFF;
114 *p
++ = (sig
->SealAlgorithm
>> 8) & 0xFF;
115 *p
++ = (sig
->Pad
>> 0) & 0xFF;
116 *p
++ = (sig
->Pad
>> 8) & 0xFF;
117 *p
++ = (sig
->Flags
>> 0) & 0xFF;
118 *p
++ = (sig
->Flags
>> 8) & 0xFF;
120 if (len
> NL_AUTH_SIGNATURE_HEADER_LENGTH
) {
121 memcpy(p
, sig
->SequenceNumber
, 8);
125 if (len
> NL_AUTH_SIGNATURE_COMMON_LENGTH
) {
126 size_t cksumlen
= _netlogon_checksum_length(sig
);
128 memcpy(p
, sig
->Checksum
, cksumlen
);
131 /* Confounder, if present, is immediately after checksum */
132 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
) {
133 memcpy(p
, &sig
->Checksum
[cksumlen
], 8);
141 _netlogon_decode_NL_AUTH_SIGNATURE(const uint8_t *ptr
,
143 NL_AUTH_SIGNATURE
*sig
)
145 const uint8_t *p
= ptr
;
148 if (len
< NL_AUTH_SIGNATURE_COMMON_LENGTH
)
149 return KRB5_BAD_MSIZE
;
151 sig
->SignatureAlgorithm
= (p
[0] << 0) | (p
[1] << 8);
152 sig
->SealAlgorithm
= (p
[2] << 0) | (p
[3] << 8);
153 sig
->Pad
= (p
[4] << 0) | (p
[5] << 8);
154 sig
->Flags
= (p
[6] << 0) | (p
[7] << 8);
157 memcpy(sig
->SequenceNumber
, p
, 8);
160 /* Validate signature algorithm is known and matches enctype */
161 switch (sig
->SignatureAlgorithm
) {
162 case NL_SIGN_ALG_HMAC_MD5
:
163 cksumlen
= NL_AUTH_SIGNATURE_LENGTH
;
165 case NL_SIGN_ALG_SHA256
:
166 cksumlen
= NL_AUTH_SHA2_SIGNATURE_LENGTH
;
173 if (sig
->SealAlgorithm
== NL_SEAL_ALG_NONE
)
174 cksumlen
-= 8; /* confounder is optional if no sealing */
177 return KRB5_BAD_MSIZE
;
179 /* Copy variable length checksum */
180 cksumlen
= _netlogon_checksum_length(sig
);
181 memcpy(sig
->Checksum
, p
, cksumlen
);
184 /* Copy confounder in past checksum */
185 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
)
186 memcpy(&sig
->Checksum
[cksumlen
], p
, 8);
192 _netlogon_derive_rc4_hmac_key(uint8_t key
[16],
195 EVP_CIPHER_CTX
*rc4Key
,
198 uint8_t tmpData
[MD5_DIGEST_LENGTH
];
199 uint8_t derivedKey
[MD5_DIGEST_LENGTH
];
200 unsigned int len
= MD5_DIGEST_LENGTH
;
202 HMAC(EVP_md5(), key
, 16, zeros
, sizeof(zeros
), tmpData
, &len
);
203 HMAC(EVP_md5(), tmpData
, MD5_DIGEST_LENGTH
,
204 salt
, saltLength
, derivedKey
, &len
);
206 assert(len
== MD5_DIGEST_LENGTH
);
208 EVP_CipherInit_ex(rc4Key
, EVP_rc4(), NULL
, derivedKey
, NULL
, enc
);
210 memset(derivedKey
, 0, sizeof(derivedKey
));
214 _netlogon_derive_rc4_seal_key(gssnetlogon_ctx ctx
,
215 NL_AUTH_SIGNATURE
*sig
,
216 EVP_CIPHER_CTX
*sealkey
,
222 for (i
= 0; i
< sizeof(xorKey
); i
++) {
223 xorKey
[i
] = ctx
->SessionKey
[i
] ^ 0xF0;
226 _netlogon_derive_rc4_hmac_key(xorKey
,
227 sig
->SequenceNumber
, sizeof(sig
->SequenceNumber
), sealkey
, enc
);
229 memset(xorKey
, 0, sizeof(xorKey
));
233 _netlogon_derive_rc4_seq_key(gssnetlogon_ctx ctx
,
234 NL_AUTH_SIGNATURE
*sig
,
235 EVP_CIPHER_CTX
*seqkey
,
238 _netlogon_derive_rc4_hmac_key(ctx
->SessionKey
,
239 sig
->Checksum
, sizeof(sig
->Checksum
), seqkey
, enc
);
243 _netlogon_derive_aes_seal_key(gssnetlogon_ctx ctx
,
244 NL_AUTH_SIGNATURE
*sig
,
245 EVP_CIPHER_CTX
*sealkey
,
248 uint8_t encryptionKey
[16];
252 for (i
= 0; i
< sizeof(encryptionKey
); i
++) {
253 encryptionKey
[i
] = ctx
->SessionKey
[i
] ^ 0xF0;
256 memcpy(&ivec
[0], sig
->SequenceNumber
, 8);
257 memcpy(&ivec
[8], sig
->SequenceNumber
, 8);
259 EVP_CipherInit_ex(sealkey
, EVP_aes_128_cfb8(),
260 NULL
, encryptionKey
, ivec
, enc
);
262 memset(encryptionKey
, 0, sizeof(encryptionKey
));
266 _netlogon_derive_aes_seq_key(gssnetlogon_ctx ctx
,
267 NL_AUTH_SIGNATURE
*sig
,
268 EVP_CIPHER_CTX
*seqkey
,
273 memcpy(&ivec
[0], sig
->Checksum
, 8);
274 memcpy(&ivec
[8], sig
->Checksum
, 8);
276 EVP_CipherInit_ex(seqkey
, EVP_aes_128_cfb8(),
277 NULL
, ctx
->SessionKey
, ivec
, enc
);
281 _netlogon_seal(gssnetlogon_ctx ctx
,
282 NL_AUTH_SIGNATURE
*sig
,
283 gss_iov_buffer_desc
*iov
,
287 EVP_CIPHER_CTX sealkey
;
289 uint8_t *confounder
= _netlogon_confounder(sig
);
291 EVP_CIPHER_CTX_init(&sealkey
);
293 if (sig
->SealAlgorithm
== NL_SEAL_ALG_AES128
)
294 _netlogon_derive_aes_seal_key(ctx
, sig
, &sealkey
, enc
);
296 _netlogon_derive_rc4_seal_key(ctx
, sig
, &sealkey
, enc
);
298 EVP_Cipher(&sealkey
, confounder
, confounder
, 8);
301 * For RC4, Windows resets the cipherstate after encrypting
302 * the confounder, thus defeating the purpose of the confounder
304 if (sig
->SealAlgorithm
== NL_SEAL_ALG_RC4
) {
305 EVP_CipherFinal_ex(&sealkey
, NULL
, &i
);
306 _netlogon_derive_rc4_seal_key(ctx
, sig
, &sealkey
, enc
);
309 for (i
= 0; i
< iov_count
; i
++) {
310 gss_iov_buffer_t iovp
= &iov
[i
];
312 switch (GSS_IOV_BUFFER_TYPE(iovp
->type
)) {
313 case GSS_IOV_BUFFER_TYPE_DATA
:
314 case GSS_IOV_BUFFER_TYPE_PADDING
:
315 EVP_Cipher(&sealkey
, iovp
->buffer
.value
, iovp
->buffer
.value
,
316 iovp
->buffer
.length
);
323 EVP_CipherFinal_ex(&sealkey
, NULL
, &i
);
324 EVP_CIPHER_CTX_cleanup(&sealkey
);
328 _netlogon_seq(gssnetlogon_ctx ctx
,
329 NL_AUTH_SIGNATURE
*sig
,
332 EVP_CIPHER_CTX seqkey
;
334 EVP_CIPHER_CTX_init(&seqkey
);
336 if (sig
->SignatureAlgorithm
== NL_SIGN_ALG_SHA256
)
337 _netlogon_derive_aes_seq_key(ctx
, sig
, &seqkey
, enc
);
339 _netlogon_derive_rc4_seq_key(ctx
, sig
, &seqkey
, enc
);
341 EVP_Cipher(&seqkey
, sig
->SequenceNumber
, sig
->SequenceNumber
, 8);
343 EVP_CIPHER_CTX_cleanup(&seqkey
);
347 _netlogon_digest_md5(gssnetlogon_ctx ctx
,
348 NL_AUTH_SIGNATURE
*sig
,
349 gss_iov_buffer_desc
*iov
,
354 uint8_t header
[NL_AUTH_SIGNATURE_HEADER_LENGTH
];
355 uint8_t digest
[MD5_DIGEST_LENGTH
];
356 unsigned int md_len
= MD5_DIGEST_LENGTH
;
359 _netlogon_encode_NL_AUTH_SIGNATURE(sig
, header
, sizeof(header
));
361 md5
= EVP_MD_CTX_create();
362 EVP_DigestInit_ex(md5
, EVP_md5(), NULL
);
363 EVP_DigestUpdate(md5
, zeros
, sizeof(zeros
));
364 EVP_DigestUpdate(md5
, header
, sizeof(header
));
366 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
) {
367 EVP_DigestUpdate(md5
, sig
->Confounder
, sizeof(sig
->Confounder
));
370 for (i
= 0; i
< iov_count
; i
++) {
371 gss_iov_buffer_t iovp
= &iov
[i
];
373 switch (GSS_IOV_BUFFER_TYPE(iovp
->type
)) {
374 case GSS_IOV_BUFFER_TYPE_DATA
:
375 case GSS_IOV_BUFFER_TYPE_PADDING
:
376 case GSS_IOV_BUFFER_TYPE_SIGN_ONLY
:
377 EVP_DigestUpdate(md5
, iovp
->buffer
.value
, iovp
->buffer
.length
);
384 EVP_DigestFinal_ex(md5
, digest
, NULL
);
385 EVP_MD_CTX_destroy(md5
);
387 HMAC(EVP_md5(), ctx
->SessionKey
, sizeof(ctx
->SessionKey
),
388 digest
, sizeof(digest
), digest
, &md_len
);
389 memcpy(md
, digest
, 8);
393 _netlogon_digest_sha256(gssnetlogon_ctx ctx
,
394 NL_AUTH_SIGNATURE
*sig
,
395 gss_iov_buffer_desc
*iov
,
400 uint8_t header
[NL_AUTH_SIGNATURE_HEADER_LENGTH
];
401 uint8_t digest
[SHA256_DIGEST_LENGTH
];
402 unsigned int md_len
= SHA256_DIGEST_LENGTH
;
405 /* Encode first 8 bytes of signature into header */
406 _netlogon_encode_NL_AUTH_SIGNATURE(sig
, header
, sizeof(header
));
408 HMAC_CTX_init(&hmac
);
409 HMAC_Init_ex(&hmac
, ctx
->SessionKey
, sizeof(ctx
->SessionKey
),
411 HMAC_Update(&hmac
, header
, sizeof(header
));
413 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
) {
415 * If the checksum length bug is ever fixed, then be sure to
416 * update this code to point to &sig->Checksum[32] as that is
417 * where the confounder is supposed to be.
419 HMAC_Update(&hmac
, sig
->Confounder
, 8);
422 for (i
= 0; i
< iov_count
; i
++) {
423 gss_iov_buffer_t iovp
= &iov
[i
];
425 switch (GSS_IOV_BUFFER_TYPE(iovp
->type
)) {
426 case GSS_IOV_BUFFER_TYPE_DATA
:
427 case GSS_IOV_BUFFER_TYPE_PADDING
:
428 case GSS_IOV_BUFFER_TYPE_SIGN_ONLY
:
429 HMAC_Update(&hmac
, iovp
->buffer
.value
, iovp
->buffer
.length
);
436 HMAC_Final(&hmac
, digest
, &md_len
);
437 HMAC_CTX_cleanup(&hmac
);
438 memcpy(md
, digest
, 8);
442 _netlogon_digest(gssnetlogon_ctx ctx
,
443 NL_AUTH_SIGNATURE
*sig
,
444 gss_iov_buffer_desc
*iov
,
448 if (sig
->SignatureAlgorithm
== NL_SIGN_ALG_SHA256
)
449 _netlogon_digest_sha256(ctx
, sig
, iov
, iov_count
, md
);
451 _netlogon_digest_md5(ctx
, sig
, iov
, iov_count
, md
);
455 _netlogon_wrap_iov(OM_uint32
* minor_status
,
456 gss_ctx_id_t context_handle
,
460 gss_iov_buffer_desc
*iov
,
464 gss_iov_buffer_t header
;
465 NL_AUTH_SIGNATURE_U sigbuf
= { { 0 } };
466 NL_AUTH_SIGNATURE
*sig
= NL_AUTH_SIGNATURE_P(&sigbuf
);
467 gssnetlogon_ctx ctx
= (gssnetlogon_ctx
)context_handle
;
471 if (ctx
->State
!= NL_AUTH_ESTABLISHED
) {
472 *minor_status
= EINVAL
;
473 return GSS_S_FAILURE
;
476 header
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_HEADER
);
477 if (header
== NULL
) {
478 *minor_status
= EINVAL
;
479 return GSS_S_FAILURE
;
482 size
= _netlogon_signature_length(ctx
->SignatureAlgorithm
, conf_req_flag
);
484 if (GSS_IOV_BUFFER_FLAGS(header
->type
) & GSS_IOV_BUFFER_FLAG_ALLOCATE
) {
485 ret
= _gss_mg_allocate_buffer(minor_status
, header
, size
);
488 } else if (header
->buffer
.length
< size
) {
489 *minor_status
= KRB5_BAD_MSIZE
;
490 return GSS_S_FAILURE
;
492 header
->buffer
.length
= size
;
495 memset(header
->buffer
.value
, 0, header
->buffer
.length
);
497 sig
->SignatureAlgorithm
= ctx
->SignatureAlgorithm
;
498 sig
->SealAlgorithm
= conf_req_flag
? ctx
->SealAlgorithm
: NL_SEAL_ALG_NONE
;
501 krb5_generate_random_block(_netlogon_confounder(sig
), 8);
503 sig
->Pad
= 0xFFFF; /* [MS-NRPC] 3.3.4.2.1.3 */
504 sig
->Flags
= 0; /* [MS-NRPC] 3.3.4.2.1.4 */
505 HEIMDAL_MUTEX_lock(&ctx
->Mutex
);
506 _netlogon_encode_sequence_number(ctx
->SequenceNumber
, sig
->SequenceNumber
,
507 ctx
->LocallyInitiated
);
508 ctx
->SequenceNumber
++;
509 HEIMDAL_MUTEX_unlock(&ctx
->Mutex
);
511 /* [MS-NRPC] 3.3.4.2.1.7: sign header, optional confounder and data */
512 _netlogon_digest(ctx
, sig
, iov
, iov_count
, sig
->Checksum
);
514 /* [MS-NRPC] 3.3.4.2.1.8: optionally encrypt confounder and data */
516 _netlogon_seal(ctx
, sig
, iov
, iov_count
, 1);
518 /* [MS-NRPC] 3.3.4.2.1.9: encrypt sequence number */
519 _netlogon_seq(ctx
, sig
, 1);
521 _netlogon_encode_NL_AUTH_SIGNATURE(sig
, header
->buffer
.value
,
522 header
->buffer
.length
);
524 if (conf_state
!= NULL
)
525 *conf_state
= conf_req_flag
;
528 return GSS_S_COMPLETE
;
532 _netlogon_unwrap_iov(OM_uint32
*minor_status
,
533 gss_ctx_id_t context_handle
,
535 gss_qop_t
*qop_state
,
536 gss_iov_buffer_desc
*iov
,
540 gss_iov_buffer_t header
;
541 NL_AUTH_SIGNATURE_U sigbuf
;
542 NL_AUTH_SIGNATURE
*sig
= NL_AUTH_SIGNATURE_P(&sigbuf
);
543 gssnetlogon_ctx ctx
= (gssnetlogon_ctx
)context_handle
;
544 uint8_t checksum
[SHA256_DIGEST_LENGTH
];
545 uint64_t SequenceNumber
;
547 if (ctx
->State
!= NL_AUTH_ESTABLISHED
) {
548 *minor_status
= EINVAL
;
549 return GSS_S_FAILURE
;
552 header
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_HEADER
);
553 if (header
== NULL
) {
554 *minor_status
= EINVAL
;
555 return GSS_S_FAILURE
;
558 ret
= _netlogon_decode_NL_AUTH_SIGNATURE(header
->buffer
.value
,
559 header
->buffer
.length
,
563 return GSS_S_DEFECTIVE_TOKEN
;
566 /* [MS-NRPC] 3.3.4.2.2.1: verify signature algorithm selection */
567 if (sig
->SignatureAlgorithm
!= ctx
->SignatureAlgorithm
)
568 return GSS_S_BAD_SIG
;
570 /* [MS-NRPC] 3.3.4.2.2.2: verify encryption algorithm selection */
571 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
&&
572 sig
->SealAlgorithm
!= ctx
->SealAlgorithm
)
573 return GSS_S_DEFECTIVE_TOKEN
;
575 /* [MS-NRPC] 3.3.4.2.2.3: verify Pad bytes */
576 if (sig
->Pad
!= 0xFFFF)
577 return GSS_S_DEFECTIVE_TOKEN
;
579 /* [MS-NRPC] 3.3.4.2.2.5: decrypt sequence number */
580 _netlogon_seq(ctx
, sig
, 0);
582 /* [MS-NRPC] 3.3.4.2.2.6: decode sequence number */
583 if (_netlogon_decode_sequence_number(sig
->SequenceNumber
, &SequenceNumber
,
584 !ctx
->LocallyInitiated
) != 0)
585 return GSS_S_UNSEQ_TOKEN
;
587 /* [MS-NRPC] 3.3.4.2.2.9: decrypt confounder and data */
588 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
)
589 _netlogon_seal(ctx
, sig
, iov
, iov_count
, 0);
591 /* [MS-NRPC] 3.3.4.2.2.10: verify signature */
592 _netlogon_digest(ctx
, sig
, iov
, iov_count
, checksum
);
593 if (memcmp(sig
->Checksum
, checksum
, _netlogon_checksum_length(sig
)) != 0)
594 return GSS_S_BAD_SIG
;
596 HEIMDAL_MUTEX_lock(&ctx
->Mutex
);
597 if (SequenceNumber
!= ctx
->SequenceNumber
) {
598 /* [MS-NRPC] 3.3.4.2.2.7: check sequence number */
599 ret
= GSS_S_UNSEQ_TOKEN
;
601 /* [MS-NRPC] 3.3.4.2.2.8: increment sequence number */
602 ctx
->SequenceNumber
++;
603 ret
= GSS_S_COMPLETE
;
605 HEIMDAL_MUTEX_unlock(&ctx
->Mutex
);
607 if (conf_state
!= NULL
)
608 *conf_state
= (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
);
609 if (qop_state
!= NULL
)
610 *qop_state
= GSS_C_QOP_DEFAULT
;
617 _netlogon_wrap_iov_length(OM_uint32
* minor_status
,
618 gss_ctx_id_t context_handle
,
622 gss_iov_buffer_desc
*iov
,
626 gss_iov_buffer_t iovp
;
627 gssnetlogon_ctx ctx
= (gssnetlogon_ctx
)context_handle
;
630 iovp
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_HEADER
);
632 *minor_status
= EINVAL
;
633 return GSS_S_FAILURE
;
636 len
= NL_AUTH_SIGNATURE_COMMON_LENGTH
;
637 if (ctx
->SignatureAlgorithm
== NL_SIGN_ALG_SHA256
)
638 len
+= 32; /* SHA2 checksum size */
640 len
+= 8; /* HMAC checksum size */
642 len
+= 8; /* counfounder */
644 iovp
->buffer
.length
= len
;
646 iovp
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_PADDING
);
648 iovp
->buffer
.length
= 0;
650 iovp
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_TRAILER
);
652 iovp
->buffer
.length
= 0;
654 if (conf_state
!= NULL
)
655 *conf_state
= conf_req_flag
;
658 return GSS_S_COMPLETE
;
661 OM_uint32 _netlogon_get_mic
662 (OM_uint32
* minor_status
,
663 const gss_ctx_id_t context_handle
,
665 const gss_buffer_t message_buffer
,
666 gss_buffer_t message_token
669 gss_iov_buffer_desc iov
[2];
672 iov
[0].type
= GSS_IOV_BUFFER_TYPE_DATA
;
673 iov
[0].buffer
= *message_buffer
;
674 iov
[1].type
= GSS_IOV_BUFFER_TYPE_HEADER
| GSS_IOV_BUFFER_FLAG_ALLOCATE
;
675 iov
[1].buffer
.length
= 0;
676 iov
[1].buffer
.value
= NULL
;
678 ret
= _netlogon_wrap_iov(minor_status
, context_handle
, 0,
679 qop_req
, NULL
, iov
, 2);
680 if (ret
== GSS_S_COMPLETE
)
681 *message_token
= iov
[1].buffer
;
688 (OM_uint32
* minor_status
,
689 const gss_ctx_id_t context_handle
,
690 const gss_buffer_t message_buffer
,
691 const gss_buffer_t token_buffer
,
692 gss_qop_t
* qop_state
695 gss_iov_buffer_desc iov
[2];
697 iov
[0].type
= GSS_IOV_BUFFER_TYPE_DATA
;
698 iov
[0].buffer
= *message_buffer
;
699 iov
[1].type
= GSS_IOV_BUFFER_TYPE_HEADER
;
700 iov
[1].buffer
= *token_buffer
;
702 return _netlogon_unwrap_iov(minor_status
, context_handle
,
703 NULL
, qop_state
, iov
, 2);
707 _netlogon_wrap_size_limit (
708 OM_uint32
* minor_status
,
709 const gss_ctx_id_t context_handle
,
712 OM_uint32 req_output_size
,
713 OM_uint32
*max_input_size
716 gss_iov_buffer_desc iov
[1];
719 iov
[0].type
= GSS_IOV_BUFFER_TYPE_HEADER
;
720 iov
[0].buffer
.length
= 0;
722 ret
= _netlogon_wrap_iov_length(minor_status
, context_handle
,
723 conf_req_flag
, qop_req
, NULL
,
724 iov
, sizeof(iov
)/sizeof(iov
[0]));
728 if (req_output_size
< iov
[0].buffer
.length
)
731 *max_input_size
= req_output_size
- iov
[0].buffer
.length
;
733 return GSS_S_COMPLETE
;