Repository: dotnet/runtime
File: src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs (C#)

Code before:
                    CreateNtlmNegotiateMessage(_negotiateMessage, requiredFlags);

                    outgoingBlob = _negotiateMessage;
                    statusCode = NegotiateAuthenticationStatusCode.ContinueNeeded;
                }
                else
                {
                    Debug.Assert(!incomingBlob.IsEmpty);
                    _isAuthenticated = true;
                    outgoingBlob = ProcessChallenge(incomingBlob, out statusCode);
                }

                return outgoingBlob;
            }

            private static unsafe void CreateNtlmNegotiateMessage(Span<byte> asBytes, Flags requiredFlags)
            {
                Debug.Assert(HeaderLength == NtlmHeader.Length);
                Debug.Assert(asBytes.Length == sizeof(NegotiateMessage));

                ref NegotiateMessage message = ref MemoryMarshal.AsRef<NegotiateMessage>(asBytes);

                asBytes.Clear();
                NtlmHeader.CopyTo(asBytes);
                message.Header.MessageType = MessageType.Negotiate;
                message.Flags = BitConverter.IsLittleEndian ? requiredFlags : (Flags)BinaryPrimitives.ReverseEndianness((uint)requiredFlags);
                message.Version = s_version;
                if (!BitConverter.IsLittleEndian) message.Version.ProductBuild = (ushort)BinaryPrimitives.ReverseEndianness((ushort)message.Version.ProductBuild);
            }

            private static unsafe int GetFieldLength(MessageField field)
            {
                ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(&field, sizeof(MessageField));
                return BinaryPrimitives.ReadInt16LittleEndian(span);
            }

            private static unsafe int GetFieldOffset(MessageField field)
            {
                ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(&field, sizeof(MessageField));
                return BinaryPrimitives.ReadInt16LittleEndian(span.Slice(4));
            }

            private static ReadOnlySpan<byte> GetField(MessageField field, ReadOnlySpan<byte> payload)
            {
                int offset = GetFieldOffset(field);
                int length = GetFieldLength(field);

                if (length == 0 || offset + length > payload.Length)
                {
                    return ReadOnlySpan<byte>.Empty;
                }

Review comment (bug):
I am not a big fan of those manual branches. For one, when you look at `message.Flags` using a debugger, the value will be misrepresented on BE systems, and if you miss one place, you end up with hard to debug bugs. Other questions arise from looking at the code like why do we reverse some properties and not others....

Can we modify the definition of NegotiateMessage to have setter/getter of those properties handle the endianness difference transparently to the caller?

Code after:
            {
                byte[]? outgoingBlob;

                // TODO: Logging, validation
                if (_negotiateMessage == null)
                {
                    Debug.Assert(incomingBlob.IsEmpty);

                    Flags requiredFlags = s_requiredFlags;
                    if (_protectionLevel == ProtectionLevel.EncryptAndSign)
                    {
                        requiredFlags |= Flags.NegotiateSeal;
                    }

                    _negotiateMessage = new byte[sizeof(NegotiateMessage)];
                    CreateNtlmNegotiateMessage(_negotiateMessage, requiredFlags);

                    outgoingBlob = _negotiateMessage;
                    statusCode = NegotiateAuthenticationStatusCode.ContinueNeeded;
                }
                else
                {
                    Debug.Assert(!incomingBlob.IsEmpty);
                    _isAuthenticated = true;
                    outgoingBlob = ProcessChallenge(incomingBlob, out statusCode);
                }

                return outgoingBlob;
            }

            private static unsafe void CreateNtlmNegotiateMessage(Span<byte> asBytes, Flags requiredFlags)
            {
                Debug.Assert(HeaderLength == NtlmHeader.Length);
                Debug.Assert(asBytes.Length == sizeof(NegotiateMessage));

                ref NegotiateMessage message = ref MemoryMarshal.AsRef<NegotiateMessage>(asBytes);

                asBytes.Clear();
                NtlmHeader.CopyTo(asBytes);
                message.Header.MessageType = MessageType.Negotiate;
                message.Flags = requiredFlags;
                message.Version = s_version;
            }

            private static unsafe int GetFieldLength(MessageField field)
            {
                ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(&field, sizeof(MessageField));
                return BinaryPrimitives.ReadInt16LittleEndian(span);
            }

            private static unsafe int GetFieldOffset(MessageField field)