Discussion:
Questions on gss_verify_mic_iov / KRB5_BAD_MSIZE
Natalie Li
2015-09-15 16:04:16 UTC
Permalink
1) Is it intended for supporting GSS_VerifyMICEx() call [support
multiple input buffers] mentioned in MS-KILE document as shown below?
https://msdn.microsoft.com/en-us/library/cc233937.aspx
2) If yes to (1), then can you please confirm the usage of
gss_verify_mic_iov() in the following scenario described by MS-RPCE
<snippet - MS-RPCE>
If the client and server Supports Header Signing Flag is TRUE, the
party that sends the PDU asks the security provider to apply the
following protection to the different PDU segments.
Authentication level | PDU header | PDU body |sec_trailer
-------------------------------------------------------------------------------
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY |Integrity |Integrity | Integrity
The PDU header, PDU body, and sec_trailer MUST be passed in the
input message, in this order, to GSS_WrapEx, GSS_UnwrapEx,
GSS_GetMICEx, and GSS_VerifyMICEx. For integrity protection the sign
flag for that PDU segment MUST be set to TRUE, else it MUST be set
to FALSE.
<snippet>
<snippet - MS-KILE>
*
signed BOOLEAN <-----------------------------
*
data OCTET STRING
<snippet>
Based on the MS documentation above where "signed" flag should be set
for the various PDU segments, should the iov array be populated as
gss_iov_buffer_desc iov[4];
/* PDU header */
iov[0].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
iov[0].buffer.value = <PDU header of the incoming message>
iov[0].buffer.length = <PDU header length>
/* PDU body */
iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
iov[1].buffer.value = <PDU body of the incoming message>
iov[1].buffer.length = <PDU body length>
/* sec_trailer */
iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
iov[2].buffer.value = <sec_trailer of the incoming message>
iov[2].buffer.length = <sec_trailer length>
/* MIC token */
iov[3].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN;
iov[3].buffer.value = <MIC token in the incoming message to be verified>
iov[3].buffer.length = <MIC token length>
major = gss_verify_mic_iov(&minor, gss_ctx, &qop_state, iov, 4);
3) I've looked at the MIT krb documentation but still not clear on the
various GSS_C_BUFFER_TYPE_XXX macros.
a) Is GSS_C_BUFFER_TYPE_TRAILER intended for sec_trailer mentioned in
section 2.2.2.11 as shown below?
https://msdn.microsoft.com/en-us/library/cc243931.aspx
One of the Solaris Kerberos team members suggested that
-> libgssapi_krb5:kg_verify_checksum_iov_v3(0xd0dee6210, 0x10, 0x10,
0xd0dfe5610, 0x19, 0x7ffe0a607bf0)
-> libgssapi_krb5:checksum_iov_v3(0xd0dee6210, 0x10, 0x10,
0xd0dfe5610, 0x19, 0x7ffe0a607bf0)
-> libgssapi_krb5:kg_locate_header_iov(0x7ffe0a607bf0, 0x4,
0x101, 0x6, 0x19, 0x7ffe0a607bf0)
<- libgssapi_krb5:kg_locate_header_iov() = 0x7ffe0a607c38
-> libgssapi_krb5:kg_locate_iov(0x7ffe0a607bf0, 0x4, 0x7,
0x7ffe0a607bd8, 0x19, 0x7ffe0a607bf0)
<- libgssapi_krb5:kg_locate_iov() = 0
<--GSS_C_BUFFER_TYPE_TRAILER(0x7) not found
<- libgssapi_krb5:checksum_iov_v3() = 0x96c73abe
<- libgssapi_krb5:kg_verify_checksum_iov_v3() = 0x96c73abe
<- libgssapi_krb5:gss_krb5int_unseal_v3_iov() = 0x60000
However, added another iov[4] of type TRAILER and the
gss_verify_mic_iov() still fail in other place.
To be specific, I'm seeing the following error message in either case:

(GSS major error): A token had an invalid Message Integrity Check (MIC)
(GSS minor error): Message size is incompatible with encryption type

Thanks,

Natalie
b) GSS_C_BUFFER_TYPE_HEADER is not intended for the PDU header (MS-RPC
header) mentioned in (2), right? The MIT krb doc suggests that for
GSSAPI wrap token header.
c) Is GSS_C_BUFFER_TYPE_DATA used only for encryption, not for signing?
Thanks,
Natalie
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Greg Hudson
2015-09-16 01:10:09 UTC
Permalink
1) Is it intended for supporting GSS_VerifyMICEx() call [support
multiple input buffers] mentioned in MS-KILE document as shown below?
https://msdn.microsoft.com/en-us/library/cc233937.aspx
Not specifically, but it should serve a similar function, and it seems
like they should interoperate.
2) If yes to (1), then can you please confirm the usage of
gss_verify_mic_iov() in the following scenario described by MS-RPCE
[...]

It seems right to me.
a) Is GSS_C_BUFFER_TYPE_TRAILER intended for sec_trailer mentioned in
section 2.2.2.11 as shown below?
https://msdn.microsoft.com/en-us/library/cc243931.aspx
No, it's used by gss_wrap_iov()/gss_unwrap_iov() for the RFC 3961
authentication trailer. Microsoft's implementation rotates this into
the header; we do the same if no trailer buffer is given.
gss_verify_mic_iov() does not use this buffer type.
One of the Solaris Kerberos team members suggested that
[...]
No; the logic is somewhat tortured due to the way code is shared between
unwrap and verify_iov, but checksum_iov_v3() doesn't require a trailer
in the verify_iov case because rrc is set to a synthetic value.
(GSS major error): A token had an invalid Message Integrity Check (MIC)
(GSS minor error): Message size is incompatible with encryption type
What is the encryption type of the session key, and what is the size of
the MIC token?
b) GSS_C_BUFFER_TYPE_HEADER is not intended for the PDU header (MS-RPC
header) mentioned in (2), right? The MIT krb doc suggests that for
GSSAPI wrap token header.
Correct, the MS-RPC PDU header is at a higher protocol layer.
c) Is GSS_C_BUFFER_TYPE_DATA used only for encryption, not for signing?
GSS_C_BUFFER_TYPE_DATA and GSS_IOV_BUFFER_TYPE_SIGN_ONLY are both used
for signing. They have the same meaning to the MIC functions, but have
different meanings for gss_wrap_iov(), where DATA buffers are encrypted
and SIGN_ONLY buffers are not--but again, both types are included in the
calculation of the authentication tag.
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Natalie Li
2015-09-16 04:29:56 UTC
Permalink
Post by Greg Hudson
1) Is it intended for supporting GSS_VerifyMICEx() call [support
multiple input buffers] mentioned in MS-KILE document as shown below?
https://msdn.microsoft.com/en-us/library/cc233937.aspx
Not specifically, but it should serve a similar function, and it seems
like they should interoperate.
2) If yes to (1), then can you please confirm the usage of
gss_verify_mic_iov() in the following scenario described by MS-RPCE
[...]
It seems right to me.
Thanks for checking.
Post by Greg Hudson
a) Is GSS_C_BUFFER_TYPE_TRAILER intended for sec_trailer mentioned in
section 2.2.2.11 as shown below?
https://msdn.microsoft.com/en-us/library/cc243931.aspx
No, it's used by gss_wrap_iov()/gss_unwrap_iov() for the RFC 3961
authentication trailer. Microsoft's implementation rotates this into
the header; we do the same if no trailer buffer is given.
gss_verify_mic_iov() does not use this buffer type.
That's what I thought as well.
Post by Greg Hudson
(GSS major error): A token had an invalid Message Integrity Check (MIC)
(GSS minor error): Message size is incompatible with encryption type
What is the encryption type of the session key, and what is the size of
the MIC token?
EType: aes256-cts-hmac-sha1-96 (18) as shown in frame 25. See (1) of the
attached doc.

Size of the MIC token is 32 bytes as shown in frame 37. See (2) of the
attache doc.

Here's the MIC token as seen on wire (See (3) of the attached doc):

<snippet>
- GssApi:
- Token: unused (0)
- MsKerberosToken: unused (0)
TokId: GSS_GetMIC (0x404)
- Krb5GssV2GetMic:
+ Flags: 4 (0x4)
Filler: Binary Large Object (5 Bytes)
SndSeq: 1536586973 (0x5B9674DD)
SgnCksum: Binary Large Object (16 Bytes)
<snippet>

Since wireshark cannot decode the relatively new MS-FSRVP protocol, I've
been using Microsoft NetMon to analyze network traces.
Attached are the network trace and a document w/ snapshots of Microsoft
NetMon.
NOTE: The frame # mentioned in this email is based on NetMon. The frame
# in NetMon may be different from the frame # in wireshark.
Post by Greg Hudson
b) GSS_C_BUFFER_TYPE_HEADER is not intended for the PDU header (MS-RPC
header) mentioned in (2), right? The MIT krb doc suggests that for
GSSAPI wrap token header.
Correct, the MS-RPC PDU header is at a higher protocol layer.
c) Is GSS_C_BUFFER_TYPE_DATA used only for encryption, not for signing?
GSS_C_BUFFER_TYPE_DATA and GSS_IOV_BUFFER_TYPE_SIGN_ONLY are both used
for signing. They have the same meaning to the MIC functions, but have
different meanings for gss_wrap_iov(), where DATA buffers are encrypted
and SIGN_ONLY buffers are not--but again, both types are included in the
calculation of the authentication tag.
Thanks for the info,

Natalie
Greg Hudson
2015-09-16 05:17:26 UTC
Permalink
Post by Natalie Li
EType: aes256-cts-hmac-sha1-96 (18) as shown in frame 25. See (1) of the
attached doc.
Size of the MIC token is 32 bytes as shown in frame 37. See (2) of the
attache doc.
The AES enctypes use a checksum length of 12 bytes. There are an
additional 16 bytes of GSSAPI token header, for an expected total of 28
bytes. In checksum_iov_v3() we check for an exact match against this
expected length, so the 32-byte token yields an error.

Looking at the packet capture, the MIC token ends with twelve non-zero
checksum bytes followed by four zero bytes, which I assume are padding.
This padding appears to conform to [MS-RPCE] 2.2.3.5; I don't know if
there is any way to find out the true length of the token without the
padding. (Removing zero bytes is of course not safe; nothing prevents
the last byte of the checksum from being zero.)
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Natalie Li
2015-09-16 18:48:08 UTC
Permalink
Thanks Greg. I just did the proof-of-concept testing by removing the
4-byte padding from the MIC token iov and confirmed that
gss_verify_mic_iov() returns successfully.

3104/***@145: ->
libgssapi_krb5:krb5_gss_verify_mic_iov(0x7ff7ff202c08, 0xe78889d10,
0x7ff7ff202c0c, 0x7ff7ff202c10, 0x4, 0x7ff807c53090)
3104/***@145: <-
libgssapi_krb5:krb5_gss_verify_mic_iov() = 0
3104/***@145: <-
libgssapi_krb5:spnego_gss_verify_mic_iov() = 0
3104/***@145: <- libgssapi_krb5:gss_verify_mic_iov() = 0
<----- SUCCESS!

Can you please tell me what's the expected length of the MIC token if
encryption type of the session key is AES128 or ARCFOUR-HMAC?
Does the checksum_iov_v3() know which encryption type to use? If so, can
it truncate the provided MIC token to the expected length before
verifying the checksum?

I've looked at various network traces and have found that the Windows
2012 R2 client sets AuthLen to 32 (most of the time) and 28
(occasionally). I'll check with Microsoft on how best we can detect the
paddings that is included in the AuthToken (i.e. the MIC token +
paddings (if any)) given at the MS-RPC layer I cannot detect such
paddings via decoding the header or sec_trailer section of the message.

Thanks,

Natalie
Post by Greg Hudson
Post by Natalie Li
EType: aes256-cts-hmac-sha1-96 (18) as shown in frame 25. See (1) of the
attached doc.
Size of the MIC token is 32 bytes as shown in frame 37. See (2) of the
attache doc.
The AES enctypes use a checksum length of 12 bytes. There are an
additional 16 bytes of GSSAPI token header, for an expected total of 28
bytes. In checksum_iov_v3() we check for an exact match against this
expected length, so the 32-byte token yields an error.
Looking at the packet capture, the MIC token ends with twelve non-zero
checksum bytes followed by four zero bytes, which I assume are padding.
This padding appears to conform to [MS-RPCE] 2.2.3.5; I don't know if
there is any way to find out the true length of the token without the
padding. (Removing zero bytes is of course not safe; nothing prevents
the last byte of the checksum from being zero.)
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Greg Hudson
2015-09-16 20:51:04 UTC
Permalink
Post by Natalie Li
Thanks Greg. I just did the proof-of-concept testing by removing the
4-byte padding from the MIC token iov and confirmed that
gss_verify_mic_iov() returns successfully.
It occurs to me that you could also concatenate the three buffers and
use gss_verify_mic(), with the same result. But by my reading of the
code, you would still have to remove the padding.
Post by Natalie Li
Can you please tell me what's the expected length of the MIC token if
encryption type of the session key is AES128 or ARCFOUR-HMAC?
28 for aes128, 32 for rc4-hmac.
Post by Natalie Li
Does the checksum_iov_v3() know which encryption type to use? If so, can
it truncate the provided MIC token to the expected length before
verifying the checksum?
That would be possible; however, I don't think we have any precedent for
allowing trailing garbage at the end of GSSAPI krb5 tokens. I think it
would be better to remove the padding at the MS-RPCE layer if it is
possible to do so, but I'm not sure whether it is.
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Natalie Li
2015-09-16 21:12:10 UTC
Permalink
Post by Greg Hudson
Post by Natalie Li
Thanks Greg. I just did the proof-of-concept testing by removing the
4-byte padding from the MIC token iov and confirmed that
gss_verify_mic_iov() returns successfully.
It occurs to me that you could also concatenate the three buffers and
use gss_verify_mic(), with the same result.
I tried that before switching to use gss_verify_mic_iov(). At that time,
I had thought that the reason why gss_verify_mic() failed w/
KRB5_BAD_MSIZE was because it's not the right API to use.
Post by Greg Hudson
But by my reading of the
code, you would still have to remove the padding.
Most likely because I got the same KRB5 error when padding was not removed.
Post by Greg Hudson
Post by Natalie Li
Can you please tell me what's the expected length of the MIC token if
encryption type of the session key is AES128 or ARCFOUR-HMAC?
28 for aes128, 32 for rc4-hmac.
Thanks.
Post by Greg Hudson
Post by Natalie Li
Does the checksum_iov_v3() know which encryption type to use? If so, can
it truncate the provided MIC token to the expected length before
verifying the checksum?
That would be possible; however, I don't think we have any precedent for
allowing trailing garbage at the end of GSSAPI krb5 tokens. I think it
would be better to remove the padding at the MS-RPCE layer if it is
possible to do so, but I'm not sure whether it is.
MS-RPC layer on the receiving end has no knowledge as to which
encryption type is used by the underlying authentication mechanism, nor
can it tell how many bytes of padding has been added to the AuthToken
(AKA MIC token) by decoding the various PDU segments of the incoming
message. So, I'm hesitate to tamper w/ the AuthToken in the incoming
message at the MS-RPC layer. It's questionable why the Windows client
sometimes sends 28-byte MIC token in some requests and 32-byte MIC token
(including the 4-byte padding) in some other requests when AES
encryption key is used. I'll check w/ Microsoft before getting back to
you on the next steps.

Thanks,

Natalie
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Natalie Li
2015-09-23 20:08:40 UTC
Permalink
Hi Greg,

One of the Microsoft engineers confirmed the following:

1) MS-RPC layer on the server should treat the Authentication Token
(i.e. MIC token + trailing zeros) in the incoming MS-RPC request as
opaque structure.

2) MS version of gss_verify_mic_iov (AKA [MS-KILE] 3.4.5.7
GSS_VerifyMICEx()) successfully verify the MIC token even when the MIC
token w/ the trailing zeros is passed as function argument.

Can the checksum_iov_v3() be updated as we previously discussed?

[I'll forward you the email exchanges that I had w/ Microsoft separately.]

Thanks,

Natalie
Post by Natalie Li
Post by Natalie Li
Thanks Greg. I just did the proof-of-concept testing by removing the
4-byte padding from the MIC token iov and confirmed that
gss_verify_mic_iov() returns successfully.
<snip>
Post by Natalie Li
Does the checksum_iov_v3() know which encryption type to use? If so, can
it truncate the provided MIC token to the expected length before
verifying the checksum?
That would be possible; however, I don't think we have any precedent for
allowing trailing garbage at the end of GSSAPI krb5 tokens. I think it
would be better to remove the padding at the MS-RPCE layer if it is
possible to do so, but I'm not sure whether it is.
MS-RPC layer on the receiving end has no knowledge as to which
encryption type is used by the underlying authentication mechanism,
nor can it tell how many bytes of padding has been added to the
AuthToken (AKA MIC token) by decoding the various PDU segments of the
incoming message. So, I'm hesitate to tamper w/ the AuthToken in the
incoming message at the MS-RPC layer. It's questionable why the
Windows client sometimes sends 28-byte MIC token in some requests and
32-byte MIC token (including the 4-byte padding) in some other
requests when AES encryption key is used. I'll check w/ Microsoft
before getting back to you on the next steps.
Thanks,
Natalie
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Greg Hudson
2015-09-26 15:48:55 UTC
Permalink
Post by Natalie Li
2) MS version of gss_verify_mic_iov (AKA [MS-KILE] 3.4.5.7
GSS_VerifyMICEx()) successfully verify the MIC token even when the MIC
token w/ the trailing zeros is passed as function argument.
Can the checksum_iov_v3() be updated as we previously discussed?
Did Luke's reply adequately address this issue? You can use
gss_get_mic_iov_length() to interrogate the context for the appropriate
length of a MIC token, and truncate the received MS-RPCE token to that
value.
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Natalie Li
2015-09-28 21:25:38 UTC
Permalink
Post by Greg Hudson
Post by Natalie Li
2) MS version of gss_verify_mic_iov (AKA [MS-KILE] 3.4.5.7
GSS_VerifyMICEx()) successfully verify the MIC token even when the MIC
token w/ the trailing zeros is passed as function argument.
Can the checksum_iov_v3() be updated as we previously discussed?
Did Luke's reply adequately address this issue? You can use
gss_get_mic_iov_length() to interrogate the context for the appropriate
length of a MIC token, and truncate the received MS-RPCE token to that
value.
Yes, it does. Thanks!
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev

Luke Howard
2015-09-24 02:32:18 UTC
Permalink
Have a look at the code on dcerpc.org in gssauthcn.c for an example (it does not need the IOV API for integrity only as the buffer is contiguous). You should be able to use get_mic_iov_length to determine how many significant bytes in the trailer.

Sent from my iPad
Post by Greg Hudson
Post by Natalie Li
Thanks Greg. I just did the proof-of-concept testing by removing the
4-byte padding from the MIC token iov and confirmed that
gss_verify_mic_iov() returns successfully.
It occurs to me that you could also concatenate the three buffers and
use gss_verify_mic(), with the same result. But by my reading of the
code, you would still have to remove the padding.
Post by Natalie Li
Can you please tell me what's the expected length of the MIC token if
encryption type of the session key is AES128 or ARCFOUR-HMAC?
28 for aes128, 32 for rc4-hmac.
Post by Natalie Li
Does the checksum_iov_v3() know which encryption type to use? If so, can
it truncate the provided MIC token to the expected length before
verifying the checksum?
That would be possible; however, I don't think we have any precedent for
allowing trailing garbage at the end of GSSAPI krb5 tokens. I think it
would be better to remove the padding at the MS-RPCE layer if it is
possible to do so, but I'm not sure whether it is.
_______________________________________________
https://mailman.mit.edu/mailman/listinfo/krbdev
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Natalie Li
2015-09-28 21:24:42 UTC
Permalink
Thanks for the pointer, Luke. Yes, gss_get_mic_iov_length() is what I need.

Natalie
Post by Luke Howard
Have a look at the code on dcerpc.org in gssauthcn.c for an example (it does not need the IOV API for integrity only as the buffer is contiguous). You should be able to use get_mic_iov_length to determine how many significant bytes in the trailer.
Sent from my iPad
Post by Greg Hudson
Post by Natalie Li
Thanks Greg. I just did the proof-of-concept testing by removing the
4-byte padding from the MIC token iov and confirmed that
gss_verify_mic_iov() returns successfully.
It occurs to me that you could also concatenate the three buffers and
use gss_verify_mic(), with the same result. But by my reading of the
code, you would still have to remove the padding.
Post by Natalie Li
Can you please tell me what's the expected length of the MIC token if
encryption type of the session key is AES128 or ARCFOUR-HMAC?
28 for aes128, 32 for rc4-hmac.
Post by Natalie Li
Does the checksum_iov_v3() know which encryption type to use? If so, can
it truncate the provided MIC token to the expected length before
verifying the checksum?
That would be possible; however, I don't think we have any precedent for
allowing trailing garbage at the end of GSSAPI krb5 tokens. I think it
would be better to remove the padding at the MS-RPCE layer if it is
possible to do so, but I'm not sure whether it is.
_______________________________________________
https://mailman.mit.edu/mailman/listinfo/krbdev
_______________________________________________
krbdev mailing list ***@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
Loading...