Add IPsec/Ikev2 support.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11219 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qianouyang 2010-12-31 10:43:54 +00:00
parent 4a8266f570
commit 9166f840d2
31 changed files with 17752 additions and 1592 deletions

View File

@ -0,0 +1,388 @@
/** @file
Cryptographic Parameter Constant Definitions from IETF;
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Ike.h"
//
// "First Oakley Default Group" from RFC2409, section 6.1.
//
// The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Modp768Modulus[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
0xA6, 0x3A, 0x36, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
//
// "Second Oakley Default Group" from RFC2409, section 6.2.
//
// The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Modp1024Modulus[] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
//
// "1536-bit MODP Group" from RFC3526, Section 2.
//
// The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Modp1536Modulus[]={
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
//
// "2048-bit MODP Group" from RFC3526, Section 3.
//
// The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Modp2048Modulus[]={
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
};
//
// "3072-bit MODP Group" from RFC3526, Section 4.
//
// The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Modp3072Modulus[]={
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
//
// "4096-bit MODP Group" from RFC3526, Section 5.
//
// The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Modp4096Modulus[]={
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
//
// "6144-bit MODP Group" from RFC3526, Section 6.
//
// The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Modp6144Modulus[]={
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
//
// "8192-bit MODP Group" from RFC3526, Section 7.
//
// The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Modp8192Modulus[]={
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
};
//
// Pre-defined Oakley MODP Groups
//
#define DH_GENERATOR_2 2
GLOBAL_REMOVE_IF_UNREFERENCED CONST MODP_GROUP OakleyModpGroup[] = {
{0, 0, NULL, 0}, //Undefined
{OakleyGroupModp768, 768, Modp768Modulus, DH_GENERATOR_2},
{OakleyGroupModp1024, 1024, Modp1024Modulus, DH_GENERATOR_2},
{0, 0, NULL, 0}, // For ECC. UnSupported
{0, 0, NULL, 0}, // For ECC. Unsupported
{OakleyGroupModp1536, 1536, Modp1536Modulus, DH_GENERATOR_2},
{0, 0, NULL, 0}, //Undefined
{0, 0, NULL, 0}, //Undefined
{0, 0, NULL, 0}, //Undefined
{0, 0, NULL, 0}, //Undefined
{0, 0, NULL, 0}, //Undefined
{0, 0, NULL, 0}, //Undefined
{0, 0, NULL, 0}, //Undefined
{0, 0, NULL, 0}, //Undefined
{OakleyGroupModp2048, 2048, Modp2048Modulus, DH_GENERATOR_2},
{OakleyGroupModp3072, 3072, Modp3072Modulus, DH_GENERATOR_2},
{OakleyGroupModp4096, 4096, Modp4096Modulus, DH_GENERATOR_2},
{OakleyGroupModp6144, 6144, Modp6144Modulus, DH_GENERATOR_2},
{OakleyGroupModp8192, 8192, Modp8192Modulus, DH_GENERATOR_2},
};

266
NetworkPkg/IpSecDxe/Ike.h Normal file
View File

@ -0,0 +1,266 @@
/** @file
The common definition of IPsec Key Exchange (IKE).
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IKE_H_
#define _IKE_H_
#include <Library/UdpIoLib.h>
#include <Library/BaseCryptLib.h>
#include "IpSecImpl.h"
#define IKE_VERSION_MAJOR_MASK 0xf0
#define IKE_VERSION_MINOR_MASK 0x0f
#define IKE_MAJOR_VERSION(v) (((v) & IKE_VERSION_MAJOR_MASK) >> 4)
#define IKE_MINOR_VERSION(v) ((v) & IKE_VERSION_MINOR_MASK)
//
// Protocol Value Use in IKEv1 and IKEv2
//
#define IPSEC_PROTO_ISAKMP 1
#define IPSEC_PROTO_IPSEC_AH 2
#define IPSEC_PROTO_IPSEC_ESP 3
#define IPSEC_PROTO_IPCOMP 4 // For IKEv1 this value is reserved
//
// For Algorithm search in support list.Last two types are for IKEv2 only.
//
#define IKE_ENCRYPT_TYPE 0
#define IKE_AUTH_TYPE 1
#define IKE_PRF_TYPE 2
#define IKE_DH_TYPE 3
//
// Encryption Algorithm present in IKEv1 phasrs2 and IKEv2 transform payload (Transform Type 1)
//
#define IPSEC_ESP_DES_IV64 1
#define IPSEC_ESP_DES 2
#define IPSEC_ESP_3DES 3
#define IPSEC_ESP_RC5 4
#define IPSEC_ESP_IDEA 5
#define IPSEC_ESP_CAST 6
#define IPSEC_ESP_BLOWFISH 7
#define IPSEC_ESP_3IDEA 8
#define IPSEC_ESP_DES_IV32 9
#define IPSEC_ESP_RC4 10 // It's reserved in IKEv2
#define IPSEC_ESP_NULL 11
#define IPSEC_ESP_AES 12
#define IKE_XCG_TYPE_NONE 0
#define IKE_XCG_TYPE_BASE 1
#define IKE_XCG_TYPE_IDENTITY_PROTECT 2
#define IKE_XCG_TYPE_AUTH_ONLY 3
#define IKE_XCG_TYPE_AGGR 4
#define IKE_XCG_TYPE_INFO 5
#define IKE_XCG_TYPE_QM 32
#define IKE_XCG_TYPE_NGM 33
#define IKE_XCG_TYPE_SA_INIT 34
#define IKE_XCG_TYPE_AUTH 35
#define IKE_XCG_TYPE_CREATE_CHILD_SA 36
#define IKE_XCG_TYPE_INFO2 37
#define IKE_LIFE_TYPE_SECONDS 1
#define IKE_LIFE_TYPE_KILOBYTES 2
//
// Deafult IKE SA lifetime and CHILD SA lifetime
//
#define IKE_SA_DEFAULT_LIFETIME 1200
#define CHILD_SA_DEFAULT_LIFETIME 3600
//
// Next payload type presented within Proposal payload
//
#define IKE_PROPOSAL_NEXT_PAYLOAD_MORE 2
#define IKE_PROPOSAL_NEXT_PAYLOAD_NONE 0
//
// Next payload type presented within Transform payload
//
#define IKE_TRANSFORM_NEXT_PAYLOAD_MORE 3
#define IKE_TRANSFORM_NEXT_PAYLOAD_NONE 0
//
// Max size of the SA attribute
//
#define MAX_SA_ATTRS_SIZE 48
#define SA_ATTR_FORMAT_BIT 0x8000
//
// The definition for Information Message ID.
//
#define INFO_MID_SIGNATURE SIGNATURE_32 ('I', 'N', 'F', 'M')
//
// Type for the IKE SESSION COMMON
//
typedef enum {
IkeSessionTypeIkeSa,
IkeSessionTypeChildSa,
IkeSessionTypeInfo,
IkeSessionTypeMax
} IKE_SESSION_TYPE;
//
// The DH Group ID defined RFC3526 and RFC 2409
//
typedef enum {
OakleyGroupModp768 = 1,
OakleyGroupModp1024 = 2,
OakleyGroupGp155 = 3, // Unsupported Now.
OakleyGroupGp185 = 4, // Unsupported Now.
OakleyGroupModp1536 = 5,
OakleyGroupModp2048 = 14,
OakleyGroupModp3072 = 15,
OakleyGroupModp4096 = 16,
OakleyGroupModp6144 = 17,
OakleyGroupModp8192 = 18,
OakleyGroupMax
} OAKLEY_GROUP_ID;
//
// IKE Header
//
#pragma pack(1)
typedef struct {
UINT64 InitiatorCookie;
UINT64 ResponderCookie;
UINT8 NextPayload;
UINT8 Version;
UINT8 ExchangeType;
UINT8 Flags;
UINT32 MessageId;
UINT32 Length;
} IKE_HEADER;
#pragma pack()
typedef union {
UINT16 AttrLength;
UINT16 AttrValue;
} IKE_SA_ATTR_UNION;
//
// SA Attribute present in Transform Payload
//
#pragma pack(1)
typedef struct {
UINT16 AttrType;
IKE_SA_ATTR_UNION Attr;
} IKE_SA_ATTRIBUTE;
#pragma pack()
//
// Contains the IKE packet information.
//
typedef struct {
UINTN RefCount;
BOOLEAN IsHdrExt;
IKE_HEADER *Header;
BOOLEAN IsPayloadsBufExt;
UINT8 *PayloadsBuf; // The whole IkePakcet trimed the IKE header.
UINTN PayloadTotalSize;
LIST_ENTRY PayloadList;
EFI_IP_ADDRESS RemotePeerIp;
BOOLEAN IsEncoded; // whether HTON is done when sending the packet
UINT32 Spi; // For the Delete Information Exchange
BOOLEAN IsDeleteInfo; // For the Delete Information Exchange
IPSEC_PRIVATE_DATA *Private; // For the Delete Information Exchange
} IKE_PACKET;
//
// The generic structure to all kinds of IKE payloads.
//
typedef struct {
UINT32 Signature;
BOOLEAN IsPayloadBufExt;
UINT8 PayloadType;
UINT8 *PayloadBuf;
UINTN PayloadSize;
LIST_ENTRY ByPacket;
} IKE_PAYLOAD;
//
// Udp Service
//
typedef struct {
UINT32 Signature;
UINT8 IpVersion;
LIST_ENTRY List;
LIST_ENTRY *ListHead;
EFI_HANDLE NicHandle;
EFI_HANDLE ImageHandle;
UDP_IO *Input;
UDP_IO *Output;
EFI_IP_ADDRESS DefaultAddress;
BOOLEAN IsConfigured;
} IKE_UDP_SERVICE;
//
// Each IKE session has its own Key sets for local peer and remote peer.
//
typedef struct {
EFI_IPSEC_ALGO_INFO LocalPeerInfo;
EFI_IPSEC_ALGO_INFO RemotePeerInfo;
} SA_KEYMATS;
//
// Each algorithm has its own Id, Guid, BlockSize and KeyLength.
// This struct contains these information for each algorithm. It is generic structure
// for both encryption and authentication algorithm.
// For authentication algorithm, the AlgSize means IcvSize. For encryption algorithm,
// it means IvSize.
//
#pragma pack(1)
typedef struct {
UINT8 AlgorithmId; // Encryption or Authentication Id used by ESP/AH
EFI_GUID *AlgGuid;
UINT8 AlgSize; // IcvSize or IvSize
UINT8 BlockSize;
UINTN KeyMateLen;
} IKE_ALG_GUID_INFO; // For IPsec Authentication and Encryption Algorithm.
#pragma pack()
//
// Structure used to store the DH group
//
typedef struct {
UINT8 GroupId;
UINTN Size;
UINT8 *Modulus;
UINTN GroupGenerator;
} MODP_GROUP;
/**
This is prototype definition of general interface to phase the payloads
after/before the decode/encode.
@param[in] SessionCommon Point to the SessionCommon
@param[in] PayloadBuf Point to the buffer of Payload.
@param[in] PayloadSize The size of the PayloadBuf in bytes.
@param[in] PayloadType The type of Payload.
**/
typedef
VOID
(*IKE_ON_PAYLOAD_FROM_NET) (
IN UINT8 *SessionCommon,
IN UINT8 *PayloadBuf,
IN UINTN PayloadSize,
IN UINT8 PayloadType
);
#endif

View File

@ -0,0 +1,255 @@
/** @file
Common operation of the IKE
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Ike.h"
#include "IkeCommon.h"
#include "IpSecConfigImpl.h"
#include "IpSecDebug.h"
//
// Initial the SPI
//
UINT32 mNextSpi = IKE_SPI_BASE;
EFI_GUID mZeroGuid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
/**
Call Crypto Lib to generate a random value with eight-octet length.
@return the 64 byte vaule.
**/
UINT64
IkeGenerateCookie (
VOID
)
{
UINT64 Cookie;
EFI_STATUS Status;
Status = IpSecCryptoIoGenerateRandomBytes ((UINT8 *)&Cookie, sizeof (UINT64));
if (EFI_ERROR (Status)) {
return 0;
} else {
return Cookie;
}
}
/**
Generate the random data for Nonce payload.
@param[in] NonceSize Size of the data in bytes.
@return Buffer which contains the random data of the spcified size.
**/
UINT8 *
IkeGenerateNonce (
IN UINTN NonceSize
)
{
UINT8 *Nonce;
EFI_STATUS Status;
Nonce = AllocateZeroPool (NonceSize);
if (Nonce == NULL) {
return NULL;
}
Status = IpSecCryptoIoGenerateRandomBytes (Nonce, NonceSize);
if (EFI_ERROR (Status)) {
FreePool (Nonce);
return NULL;
} else {
return Nonce;
}
}
/**
Convert the IKE Header from Network order to Host order.
@param[in, out] Header The pointer of the IKE_HEADER.
**/
VOID
IkeHdrNetToHost (
IN OUT IKE_HEADER *Header
)
{
Header->InitiatorCookie = NTOHLL (Header->InitiatorCookie);
Header->ResponderCookie = NTOHLL (Header->ResponderCookie);
Header->MessageId = NTOHL (Header->MessageId);
Header->Length = NTOHL (Header->Length);
}
/**
Convert the IKE Header from Host order to Network order.
@param[in, out] Header The pointer of the IKE_HEADER.
**/
VOID
IkeHdrHostToNet (
IN OUT IKE_HEADER *Header
)
{
Header->InitiatorCookie = HTONLL (Header->InitiatorCookie);
Header->ResponderCookie = HTONLL (Header->ResponderCookie);
Header->MessageId = HTONL (Header->MessageId);
Header->Length = HTONL (Header->Length);
}
/**
Allocate a buffer of IKE_PAYLOAD and set its Signature.
@return A buffer of IKE_PAYLOAD.
**/
IKE_PAYLOAD *
IkePayloadAlloc (
VOID
)
{
IKE_PAYLOAD *IkePayload;
IkePayload = (IKE_PAYLOAD *) AllocateZeroPool (sizeof (IKE_PAYLOAD));
if (IkePayload == NULL) {
return NULL;
}
IkePayload->Signature = IKE_PAYLOAD_SIGNATURE;
return IkePayload;
}
/**
Free a specified IKE_PAYLOAD buffer.
@param[in] IkePayload Pointer of IKE_PAYLOAD to be freed.
**/
VOID
IkePayloadFree (
IN IKE_PAYLOAD *IkePayload
)
{
if (IkePayload == NULL) {
return;
}
//
// If this IkePayload is not referred by others, free it.
//
if (!IkePayload->IsPayloadBufExt && (IkePayload->PayloadBuf != NULL)) {
FreePool (IkePayload->PayloadBuf);
}
FreePool (IkePayload);
}
/**
Generate an new SPI.
@return a SPI in 4 bytes.
**/
UINT32
IkeGenerateSpi (
VOID
)
{
//
// TODO: should generate SPI randomly to avoid security issue
//
return mNextSpi++;
}
/**
Generate a random data for IV
@param[in] IvBuffer The pointer of the IV buffer.
@param[in] IvSize The IV size.
@retval EFI_SUCCESS Create a random data for IV.
@retval otherwise Failed.
**/
EFI_STATUS
IkeGenerateIv (
IN UINT8 *IvBuffer,
IN UINTN IvSize
)
{
return IpSecCryptoIoGenerateRandomBytes (IvBuffer, IvSize);
}
/**
Find SPD entry by a specified SPD selector.
@param[in] SpdSel Point to SPD Selector to be searched for.
@retval Point to SPD Entry if the SPD entry found.
@retval NULL if not found.
**/
IPSEC_SPD_ENTRY *
IkeSearchSpdEntry (
IN EFI_IPSEC_SPD_SELECTOR *SpdSel
)
{
IPSEC_SPD_ENTRY *SpdEntry;
LIST_ENTRY *SpdList;
LIST_ENTRY *Entry;
SpdList = &mConfigData[IPsecConfigDataTypeSpd];
NET_LIST_FOR_EACH (Entry, SpdList) {
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
//
// Find the required SPD entry
//
if (CompareSpdSelector (
(EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
(EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
)) {
return SpdEntry;
}
}
return NULL;
}
/**
Get the IKE Version from the IKE_SA_SESSION.
@param[in] Session Pointer of the IKE_SA_SESSION.
**/
UINT8
IkeGetVersionFromSession (
IN UINT8 *Session
)
{
if (*(UINT32 *) Session == IKEV2_SA_SESSION_SIGNATURE) {
return ((IKEV2_SA_SESSION *) Session)->SessionCommon.IkeVer;
} else {
//
// Add IKEv1 support here.
//
return 0;
}
}

View File

@ -0,0 +1,191 @@
/** @file
Common operation of the IKE.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IKE_COMMON_H_
#define _IKE_COMMON_H_
#include <Protocol/Udp4.h>
#include <Protocol/Udp6.h>
#include <Protocol/Ip4Config.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/UdpIoLib.h>
#include <Library/BaseCryptLib.h>
#include "Ikev2/Ikev2.h"
#include "IpSecImpl.h"
#include "IkePacket.h"
#include "IpSecCryptIo.h"
#define IKE_DEFAULT_PORT 500
#define IKE_DEFAULT_TIMEOUT_INTERVAL 10000 // 10s
#define IKE_NONCE_SIZE 16
#define IKE_MAX_RETRY 4
#define IKE_SPI_BASE 0x10000
#define PRF_HMAC_SHA1_GUID &gEfiCryptAlgorithmSha1Guid
#define IKE_PAYLOAD_SIGNATURE SIGNATURE_32('I','K','E','P')
#define IKE_PAYLOAD_BY_PACKET(a) CR(a,IKE_PAYLOAD,ByPacket,IKE_PAYLOAD_SIGNATURE)
#define IKE_PACKET_APPEND_PAYLOAD(IkePacket,IkePayload) \
do { \
InsertTailList(&(IkePacket)->PayloadList, &(IkePayload)->ByPacket); \
} while (0)
#define IKE_PACKET_REMOVE_PAYLOAD(IkePacket,IkePayload) \
do { \
RemoveEntryList(&(IkePayload)->ByPacket); \
} while (0)
#define IKE_PACKET_END_PAYLOAD(IkePacket, Node) \
Node = GetFirstNode (&(IkePacket)->PayloadList); \
while (!IsNodeAtEnd (&(IkePacket)->PayloadList, Node)) { \
Node = GetNextNode (&(IkePacket)->PayloadList, Node); \
} \
/**
Call Crypto Lib to generate a random value with eight-octet length.
@return the 64 byte vaule.
**/
UINT64
IkeGenerateCookie (
VOID
);
/**
Generate the random data for Nonce payload.
@param[in] NonceSize Size of the data in bytes.
@return Buffer which contains the random data of the spcified size.
**/
UINT8 *
IkeGenerateNonce (
IN UINTN NonceSize
);
/**
Convert the IKE Header from Network order to Host order.
@param[in, out] Header The pointer of the IKE_HEADER.
**/
VOID
IkeHdrNetToHost (
IN OUT IKE_HEADER *Header
);
/**
Convert the IKE Header from Host order to Network order.
@param[in, out] Header The pointer of the IKE_HEADER.
**/
VOID
IkeHdrHostToNet (
IN OUT IKE_HEADER *Header
);
/**
Allocate a buffer of IKE_PAYLOAD and set its Signature.
@return A buffer of IKE_PAYLOAD.
**/
IKE_PAYLOAD *
IkePayloadAlloc (
VOID
);
/**
Free a specified IKE_PAYLOAD buffer.
@param[in] IkePayload Pointer of IKE_PAYLOAD to be freed.
**/
VOID
IkePayloadFree (
IN IKE_PAYLOAD *IkePayload
);
/**
Generate an unused SPI
@return a SPI in 4 bytes.
**/
UINT32
IkeGenerateSpi (
VOID
);
/**
Generate a random data for IV
@param[in] IvBuffer The pointer of the IV buffer.
@param[in] IvSize The IV size.
@retval EFI_SUCCESS Create a random data for IV.
@retval otherwise Failed.
**/
EFI_STATUS
IkeGenerateIv (
IN UINT8 *IvBuffer,
IN UINTN IvSize
);
/**
Get the IKE Version from the IKE_SA_SESSION.
@param[in] Session Pointer of the IKE_SA_SESSION.
**/
UINT8
IkeGetVersionFromSession (
IN UINT8 *Session
);
/**
Find SPD entry by a specified SPD selector.
@param[in] SpdSel Point to SPD Selector to be searched for.
@retval Point to Spd Entry if the SPD entry found.
@retval NULL if not found.
**/
IPSEC_SPD_ENTRY *
IkeSearchSpdEntry (
IN EFI_IPSEC_SPD_SELECTOR *SpdSel
);
extern EFI_GUID mZeroGuid;
extern MODP_GROUP OakleyModpGroup[];
extern IKE_ALG_GUID_INFO mIPsecEncrAlgInfo[];
extern IKE_ALG_GUID_INFO mIPsecAuthAlgInfo[];
#endif

View File

@ -0,0 +1,257 @@
/** @file
IKE Packet related operation.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IpSecDebug.h"
#include "Ikev2/Utility.h"
/**
Allocate a buffer for the IKE_PACKET and intitalize its Header and payloadlist.
@return The pointer of the IKE_PACKET.
**/
IKE_PACKET *
IkePacketAlloc (
VOID
)
{
IKE_PACKET *IkePacket;
IkePacket = (IKE_PACKET *) AllocateZeroPool (sizeof (IKE_PACKET));
if (IkePacket == NULL) {
return NULL;
}
IkePacket->RefCount = 1;
InitializeListHead (&IkePacket->PayloadList);
IkePacket->Header = (IKE_HEADER *) AllocateZeroPool (sizeof (IKE_HEADER));
if (IkePacket->Header == NULL) {
FreePool (IkePacket);
return NULL;
}
return IkePacket;
}
/**
Free the IkePacket by the specified IKE_PACKET pointer.
@param[in] IkePacket The pointer of the IKE_PACKET to be freed.
**/
VOID
IkePacketFree (
IN IKE_PACKET *IkePacket
)
{
LIST_ENTRY *Entry;
IKE_PAYLOAD *IkePayload;
if (IkePacket == NULL) {
return;
}
//
// Check if the Packet is referred by others.
//
if (--IkePacket->RefCount == 0) {
//
// Free IkePacket header
//
if (!IkePacket->IsHdrExt && IkePacket->Header != NULL) {
FreePool (IkePacket->Header);
}
//
// Free the PayloadsBuff
//
if (!IkePacket->IsPayloadsBufExt && IkePacket->PayloadsBuf != NULL) {
FreePool (IkePacket->PayloadsBuf);
}
//
// Iterate payloadlist and free all payloads
//
for (Entry = (IkePacket)->PayloadList.ForwardLink; Entry != &(IkePacket)->PayloadList;) {
IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);
Entry = Entry->ForwardLink;
IkePayloadFree (IkePayload);
}
FreePool (IkePacket);
}
}
/**
Callback funtion of NetbufFromExt()
@param[in] Arg The data passed from the NetBufFromExe().
**/
VOID
IkePacketNetbufFree (
IN VOID *Arg
)
{
//
// TODO: add something if need.
//
}
/**
Copy the NetBuf into a IKE_PACKET sturcture.
Create a IKE_PACKET and fill the received IKE header into the header of IKE_PACKET
and copy the recieved packet without IKE HEADER to the PayloadBuf of IKE_PACKET.
@param[in] Netbuf The pointer of the Netbuf which contains the whole received
IKE packet.
@return The pointer of the IKE_PACKET which contains the received packet.
**/
IKE_PACKET *
IkePacketFromNetbuf (
IN NET_BUF *Netbuf
)
{
IKE_PACKET *IkePacket;
IkePacket = NULL;
if (Netbuf->TotalSize < sizeof (IKE_HEADER)) {
goto Error;
}
IkePacket = IkePacketAlloc ();
if (IkePacket == NULL) {
return NULL;
}
//
// Copy the IKE header from Netbuf to IkePacket->Hdr
//
NetbufCopy (Netbuf, 0, sizeof (IKE_HEADER), (UINT8 *) IkePacket->Header);
//
// Net order to host order
//
IkeHdrNetToHost (IkePacket->Header);
if (IkePacket->Header->Length < Netbuf->TotalSize) {
goto Error;
}
IkePacket->PayloadTotalSize = IkePacket->Header->Length - sizeof (IKE_HEADER);
IkePacket->PayloadsBuf = (UINT8 *) AllocateZeroPool (IkePacket->PayloadTotalSize);
if (IkePacket->PayloadsBuf == NULL) {
goto Error;
}
//
// Copy the IKE packet without the header into the IkePacket->PayloadsBuf.
//
NetbufCopy (Netbuf, sizeof (IKE_HEADER), (UINT32) IkePacket->PayloadTotalSize, IkePacket->PayloadsBuf);
return IkePacket;
Error:
if (IkePacket != NULL) {
IkePacketFree (IkePacket);
}
return NULL;
}
/**
Convert the format from IKE_PACKET to NetBuf.
@param[in] SessionCommon Pointer of related IKE_COMMON_SESSION
@param[in] IkePacket Pointer of IKE_PACKET to be copy to NetBuf
@param[in] IkeType The IKE type to pointer the packet is for which IKE
phase. Now it supports IKE_SA_TYPE, IKE_CHILDSA_TYPE,
IKE_INFO_TYPE.
@return a pointer of Netbuff which contains the IKE_PACKE in network order.
**/
NET_BUF *
IkeNetbufFromPacket (
IN UINT8 *SessionCommon,
IN IKE_PACKET *IkePacket,
IN UINTN IkeType
)
{
NET_BUF *Netbuf;
NET_FRAGMENT *Fragments;
UINTN Index;
UINTN NumPayloads;
LIST_ENTRY *PacketEntry;
LIST_ENTRY *Entry;
IKE_PAYLOAD *IkePayload;
if (!IkePacket->IsEncoded) {
IkePacket->IsEncoded = TRUE;
//
// Convert Host order to Network order for IKE_PACKET header and payloads
// Encryption payloads if needed
//
if (((IKEV2_SESSION_COMMON *) SessionCommon)->IkeVer == 2) {
Ikev2EncodePacket ((IKEV2_SESSION_COMMON *) SessionCommon, IkePacket, IkeType);
} else {
//
//If IKEv1 support, check it here.
//
return NULL;
}
}
NumPayloads = 0;
//
// Get the number of the payloads
//
NET_LIST_FOR_EACH (PacketEntry, &(IkePacket)->PayloadList) {
NumPayloads++;
}
//
// Allocate the Framgents according to the numbers of the IkePayload
//
Fragments = (NET_FRAGMENT *) AllocateZeroPool ((1 + NumPayloads) * sizeof (NET_FRAGMENT));
if (Fragments == NULL) {
return NULL;
}
Fragments[0].Bulk = (UINT8 *) IkePacket->Header;
Fragments[0].Len = sizeof (IKE_HEADER);
Index = 0;
//
// Set payloads to the Framgments.
//
NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {
IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);
Fragments[Index + 1].Bulk = IkePayload->PayloadBuf;
Fragments[Index + 1].Len = (UINT32) IkePayload->PayloadSize;
Index++;
}
Netbuf = NetbufFromExt (
Fragments,
(UINT32) (NumPayloads + 1),
0,
0,
IkePacketNetbufFree,
NULL
);
FreePool (Fragments);
return Netbuf;
}

View File

@ -0,0 +1,82 @@
/** @file
IKE Packet related definitions and function declarations.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IKE_V1_PACKET_H_
#define _IKE_V1_PACKET_H_
#include "Ike.h"
#define IKE_PACKET_REF(p) ((p)->RefCount++)
/**
Allocate a buffer for the IKE_PACKET and intitalize its Header and payloadlist.
@return The pointer of the IKE_PACKET.
**/
IKE_PACKET *
IkePacketAlloc (
VOID
);
/**
Free the IkePacket by the specified IKE_PACKET pointer.
@param[in] IkePacket The pointer of the IKE_PACKET to be freed.
**/
VOID
IkePacketFree (
IN IKE_PACKET *IkePacket
);
/**
Copy the NetBuf into a IKE_PACKET sturcture.
Create a IKE_PACKET and fill the received IKE header into the header of IKE_PACKET
and copy the recieved packet without IKE HEADER to the PayloadBuf of IKE_PACKET.
@param[in] Netbuf The pointer of the Netbuf which contains the whole received
IKE packet.
@return The pointer of the IKE_PACKET which contains the received packet.
**/
IKE_PACKET *
IkePacketFromNetbuf (
IN NET_BUF *Netbuf
);
/**
Convert the format from IKE_PACKET to NetBuf.
@param[in] SessionCommon Pointer of related IKE_COMMON_SESSION
@param[in] IkePacket Pointer of IKE_PACKET to be copy to NetBuf
@param[in] IkeType The IKE type to pointer the packet is for which IKE
phase. Now it supports IKE_SA_TYPE, IKE_CHILDSA_TYPE,
IKE_INFO_TYPE.
@return A pointer of Netbuff which contains the contents of the IKE_PACKE in network order.
**/
NET_BUF *
IkeNetbufFromPacket (
IN UINT8 *SessionCommon,
IN IKE_PACKET *IkePacket,
IN UINTN IkeType
);
#endif

View File

@ -0,0 +1,769 @@
/** @file
Provide IPsec Key Exchange (IKE) service general interfaces.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IkeService.h"
#include "IpSecConfigImpl.h"
#include "Ikev2/Utility.h"
IKE_EXCHANGE_INTERFACE *mIkeExchange[] = {
&mIkev1Exchange,
&mIkev2Exchange
};
EFI_UDP4_CONFIG_DATA mUdp4Conf = {
FALSE,
FALSE,
FALSE,
TRUE,
//
// IO parameters
//
0,
64,
FALSE,
0,
1000000,
FALSE,
{0,0,0,0},
{0,0,0,0},
IKE_DEFAULT_PORT,
{0,0,0,0},
0
};
EFI_UDP6_CONFIG_DATA mUdp6Conf = {
FALSE,
FALSE,
TRUE,
//
// IO parameters
//
0,
128,
0,
1000000,
//Access Point
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
IKE_DEFAULT_PORT,
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
0
};
/**
Check if the NIC handle is binded to a Udp service.
@param[in] Private Pointer of IPSEC_PRIVATE_DATA.
@param[in] NicHandle The Handle of the NIC card.
@param[in] IpVersion The version of the IP stack.
@return a pointer of IKE_UDP_SERVICE.
**/
IKE_UDP_SERVICE *
IkeLookupUdp (
IN IPSEC_PRIVATE_DATA *Private,
IN EFI_HANDLE Handle,
IN UINT8 IpVersion
)
{
LIST_ENTRY *Head;
LIST_ENTRY *Entry;
LIST_ENTRY *Next;
IKE_UDP_SERVICE *Udp;
Udp = NULL;
Head = (IpVersion == IP_VERSION_4) ? &Private->Udp4List : &Private->Udp6List;
NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {
Udp = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
//
// Find the right udp service which installed on the appointed NIC handle.
//
if (Handle == Udp->NicHandle) {
break;
} else {
Udp = NULL;
}
}
return Udp;
}
/**
Configure a UDPIO's UDP4 instance.
This fuction is called by the UdpIoCreateIo() to configures a
UDP4 instance.
@param[in] UdpIo The UDP_IO to be configured.
@param[in] Context User-defined data when calling UdpIoCreateIo().
@retval EFI_SUCCESS The configuration succeeded.
@retval Others The UDP4 instance fails to configure.
**/
EFI_STATUS
IkeConfigUdp4 (
IN UDP_IO *UdpIo,
IN VOID *Context
)
{
EFI_UDP4_CONFIG_DATA Udp4Cfg;
EFI_UDP4_PROTOCOL *Udp4;
ZeroMem (&Udp4Cfg, sizeof (EFI_UDP4_CONFIG_DATA));
Udp4 = UdpIo->Protocol.Udp4;
CopyMem (
&Udp4Cfg,
&mUdp4Conf,
sizeof (EFI_UDP4_CONFIG_DATA)
);
if (Context != NULL) {
//
// Configure udp4 io with local default address.
//
Udp4Cfg.UseDefaultAddress = TRUE;
}
return Udp4->Configure (Udp4, &Udp4Cfg);
}
/**
Configure a UDPIO's UDP6 instance.
This fuction is called by the UdpIoCreateIo()to configure a
UDP6 instance.
@param[in] UdpIo The UDP_IO to be configured.
@param[in] Context User-defined data when calling UdpIoCreateIo().
@retval EFI_SUCCESS The configuration succeeded.
@retval Others The configuration fails.
**/
EFI_STATUS
IkeConfigUdp6 (
IN UDP_IO *UdpIo,
IN VOID *Context
)
{
EFI_UDP6_PROTOCOL *Udp6;
EFI_UDP6_CONFIG_DATA Udp6Cfg;
ZeroMem (&Udp6Cfg, sizeof (EFI_UDP6_CONFIG_DATA));
Udp6 = UdpIo->Protocol.Udp6;
CopyMem (
&Udp6Cfg,
&mUdp6Conf,
sizeof (EFI_UDP6_CONFIG_DATA)
);
if (Context != NULL) {
//
// Configure instance with a destination address to start source address
// selection, and then get the configure data from the mode data to store
// the source address.
//
CopyMem (
&Udp6Cfg.RemoteAddress,
Context,
sizeof (EFI_IPv6_ADDRESS)
);
}
return Udp6->Configure (Udp6, &Udp6Cfg);
}
/**
Open and configure the related output UDPIO for IKE packet sending.
If the UdpService is not configured, this fuction calls UdpIoCreatIo() to
create UDPIO to bind this UdpService for IKE packet sending. If the UdpService
has already been configured, then return.
@param[in] UdpService The UDP_IO to be configured.
@param[in] RemoteIp User-defined data when calling UdpIoCreateIo().
@retval EFI_SUCCESS The configuration is successful.
@retval Others The configuration fails.
**/
EFI_STATUS
IkeOpenOutputUdp (
IN IKE_UDP_SERVICE *UdpService,
IN EFI_IP_ADDRESS *RemoteIp
)
{
EFI_STATUS Status;
EFI_IP4_CONFIG_PROTOCOL *Ip4Cfg;
EFI_IP4_IPCONFIG_DATA *Ip4CfgData;
UINTN BufSize;
EFI_IP6_MODE_DATA Ip6ModeData;
EFI_UDP6_PROTOCOL *Udp6;
Status = EFI_SUCCESS;
Ip4CfgData = NULL;
BufSize = 0;
//
// Check whether the input and output udp io are both configured.
//
if (UdpService->IsConfigured) {
goto ON_EXIT;
}
if (UdpService->IpVersion == UDP_IO_UDP4_VERSION) {
//
// Handle ip4config protocol to get local default address.
//
Status = gBS->HandleProtocol (
UdpService->NicHandle,
&gEfiIp4ConfigProtocolGuid,
(VOID **) &Ip4Cfg
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
Status = Ip4Cfg->GetData (Ip4Cfg, &BufSize, NULL);
if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
goto ON_EXIT;
}
Ip4CfgData = AllocateZeroPool (BufSize);
if (Ip4CfgData == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Status = Ip4Cfg->GetData (Ip4Cfg, &BufSize, Ip4CfgData);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
CopyMem (
&UdpService->DefaultAddress.v4,
&Ip4CfgData->StationAddress,
sizeof (EFI_IPv4_ADDRESS)
);
//
// Create udp4 io for output with local default address.
//
UdpService->Output = UdpIoCreateIo (
UdpService->NicHandle,
UdpService->ImageHandle,
IkeConfigUdp4,
UDP_IO_UDP4_VERSION,
&UdpService->DefaultAddress
);
if (UdpService->Output == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
} else {
//
// Create udp6 io for output with remote address.
//
UdpService->Output = UdpIoCreateIo (
UdpService->NicHandle,
UdpService->ImageHandle,
IkeConfigUdp6,
UDP_IO_UDP6_VERSION,
RemoteIp
);
if (UdpService->Output == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
//
// Get ip6 mode data to get the result of source address selection.
//
ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));
Udp6 = UdpService->Output->Protocol.Udp6;
Status = Udp6->GetModeData (Udp6, NULL, &Ip6ModeData, NULL, NULL);
if (EFI_ERROR (Status)) {
UdpIoFreeIo (UdpService->Output);
goto ON_EXIT;
}
//
// Reconfigure udp6 io without remote address.
//
Udp6->Configure (Udp6, NULL);
Status = IkeConfigUdp6 (UdpService->Output, NULL);
//
// Record the selected source address for ipsec process later.
//
CopyMem (
&UdpService->DefaultAddress.v6,
&Ip6ModeData.ConfigData.StationAddress,
sizeof (EFI_IPv6_ADDRESS)
);
}
UdpService->IsConfigured = TRUE;
ON_EXIT:
if (Ip4CfgData != NULL) {
FreePool (Ip4CfgData);
}
return Status;
}
/**
Open and configure a UDPIO of Udp4 for IKE packet receiving.
This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and
UDP4 IO for each NIC handle.
@param[in] Private Point to IPSEC_PRIVATE_DATA
@param[in] Controller Handler for NIC card.
@retval EFI_SUCCESS The Operation is successful.
@retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
**/
EFI_STATUS
IkeOpenInputUdp4 (
IN IPSEC_PRIVATE_DATA *Private,
IN EFI_HANDLE Controller
)
{
IKE_UDP_SERVICE *Udp4Srv;
//
// Check whether udp4 io of the controller has already been opened.
//
Udp4Srv = IkeLookupUdp (Private, Controller, IP_VERSION_4);
if (Udp4Srv != NULL) {
return EFI_ALREADY_STARTED;
}
Udp4Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));
if (Udp4Srv == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Create udp4 io for iutput.
//
Udp4Srv->Input = UdpIoCreateIo (
Controller,
Private->ImageHandle,
IkeConfigUdp4,
UDP_IO_UDP4_VERSION,
NULL
);
if (Udp4Srv->Input == NULL) {
FreePool (Udp4Srv);
return EFI_OUT_OF_RESOURCES;
}
Udp4Srv->NicHandle = Controller;
Udp4Srv->ImageHandle = Private->ImageHandle;
Udp4Srv->ListHead = &(Private->Udp4List);
Udp4Srv->IpVersion = UDP_IO_UDP4_VERSION;
Udp4Srv->IsConfigured = FALSE;
ZeroMem (&Udp4Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));
//
// Insert the udp4 io into the list and increase the count.
//
InsertTailList (&Private->Udp4List, &Udp4Srv->List);
Private->Udp4Num++;
UdpIoRecvDatagram (Udp4Srv->Input, IkeDispatch, Udp4Srv, 0);
return EFI_SUCCESS;
}
/**
Open and configure a UDPIO of Udp6 for IKE packet receiving.
This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6
IO for each NIC handle.
@param[in] Private Point to IPSEC_PRIVATE_DATA
@param[in] Controller Handler for NIC card.
@retval EFI_SUCCESS The Operation is successful.
@retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
**/
EFI_STATUS
IkeOpenInputUdp6 (
IN IPSEC_PRIVATE_DATA *Private,
IN EFI_HANDLE Controller
)
{
IKE_UDP_SERVICE *Udp6Srv;
Udp6Srv = IkeLookupUdp (Private, Controller, IP_VERSION_6);
if (Udp6Srv != NULL) {
return EFI_ALREADY_STARTED;
}
Udp6Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));
if (Udp6Srv == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Create udp6 io for input.
//
Udp6Srv->Input = UdpIoCreateIo (
Controller,
Private->ImageHandle,
IkeConfigUdp6,
UDP_IO_UDP6_VERSION,
NULL
);
if (Udp6Srv->Input == NULL) {
FreePool (Udp6Srv);
return EFI_OUT_OF_RESOURCES;
}
Udp6Srv->NicHandle = Controller;
Udp6Srv->ImageHandle = Private->ImageHandle;
Udp6Srv->ListHead = &(Private->Udp6List);
Udp6Srv->IpVersion = UDP_IO_UDP6_VERSION;
Udp6Srv->IsConfigured = FALSE;
ZeroMem (&Udp6Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));
//
// Insert the udp6 io into the list and increase the count.
//
InsertTailList (&Private->Udp6List, &Udp6Srv->List);
Private->Udp6Num++;
UdpIoRecvDatagram (Udp6Srv->Input, IkeDispatch, Udp6Srv, 0);
return EFI_SUCCESS;
}
/**
The general interface of starting IPsec Key Exchange.
This function is called when a IKE negotiation to start getting a Key.
@param[in] UdpService Point to IKE_UDP_SERVICE which will be used for
IKE packet sending.
@param[in] SpdEntry Point to the SPD entry related to the IKE negotiation.
@param[in] RemoteIp Point to EFI_IP_ADDRESS related to the IKE negotiation.
@retval EFI_SUCCESS The Operation is successful.
@retval EFI_ACCESS_DENIED No related PAD entry was found.
@retval EFI_INVALID_PARAMETER The IKE version is not supported.
**/
EFI_STATUS
IkeNegotiate (
IN IKE_UDP_SERVICE *UdpService,
IN IPSEC_SPD_ENTRY *SpdEntry,
IN EFI_IP_ADDRESS *RemoteIp
)
{
EFI_STATUS Status;
UINT8 *IkeSaSession;
IKE_EXCHANGE_INTERFACE *Exchange;
IPSEC_PRIVATE_DATA *Private;
IPSEC_PAD_ENTRY *PadEntry;
UINT8 IkeVersion;
Private = (UdpService->IpVersion == IP_VERSION_4) ?
IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);
//
// Try to open udp io for output if it hasn't.
//
Status = IkeOpenOutputUdp (UdpService, RemoteIp);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Try to find the IKE SA session in the IKEv1 and IKEv2 established SA session list.
//
IkeSaSession = (UINT8 *) Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, RemoteIp);
if (IkeSaSession == NULL) {
//
// Find the pad entry by the remote ip address.
//
PadEntry = IpSecLookupPadEntry (UdpService->IpVersion, RemoteIp);
if (PadEntry == NULL) {
return EFI_ACCESS_DENIED;
}
//
// Determine the IKE exchange instance by the auth protocol in pad entry.
//
ASSERT (PadEntry->Data->AuthProtocol < EfiIPsecAuthProtocolMaximum);
if (PadEntry->Data->AuthProtocol == EfiIPsecAuthProtocolIKEv1) {
return EFI_INVALID_PARAMETER;
}
Exchange = mIkeExchange[PadEntry->Data->AuthProtocol];
//
// Start the main mode stage to negotiate IKE SA.
//
Status = Exchange->NegotiateSa (UdpService, SpdEntry, PadEntry, RemoteIp);
} else {
//
// Determine the IKE exchange instance by the IKE version in IKE SA session.
//
IkeVersion = IkeGetVersionFromSession (IkeSaSession);
if (IkeVersion != 2) {
return EFI_INVALID_PARAMETER;
}
Exchange = mIkeExchange[IkeVersion - 1];
//
// Start the quick mode stage to negotiate child SA.
//
Status = Exchange->NegotiateChildSa (IkeSaSession, SpdEntry, NULL);
}
return Status;
}
/**
The generic interface when receive a IKE packet.
This function is called when UDP IO receives a IKE packet.
@param[in] Packet Point to received IKE packet.
@param[in] EndPoint Point to UDP_END_POINT which contains the information of
Remote IP and Port.
@param[in] IoStatus The Status of Recieve Token.
@param[in] Context Point to data passed from the caller.
**/
VOID
IkeDispatch (
IN NET_BUF *Packet,
IN UDP_END_POINT *EndPoint,
IN EFI_STATUS IoStatus,
IN VOID *Context
)
{
IPSEC_PRIVATE_DATA *Private;
IKE_PACKET *IkePacket;
IKE_HEADER *IkeHdr;
IKE_UDP_SERVICE *UdpService;
IKE_EXCHANGE_INTERFACE *Exchange;
EFI_STATUS Status;
UdpService = (IKE_UDP_SERVICE *) Context;
IkePacket = NULL;
Private = (UdpService->IpVersion == IP_VERSION_4) ?
IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);
if (EFI_ERROR (IoStatus)) {
goto ON_EXIT;
}
//
// Check whether the ipsec is enabled or not.
//
if (Private->IpSec.DisabledFlag == TRUE) {
goto ON_EXIT;
}
if (EndPoint->RemotePort != IKE_DEFAULT_PORT) {
goto ON_EXIT;
}
//
// Build IKE packet from the received netbuf.
//
IkePacket = IkePacketFromNetbuf (Packet);
if (IkePacket == NULL) {
goto ON_EXIT;
}
//
// Get the remote address from the IKE packet.
//
if (UdpService->IpVersion == IP_VERSION_4) {
*(UINT32 *) IkePacket->RemotePeerIp.Addr = HTONL ((*(UINT32 *) EndPoint->RemoteAddr.Addr));
} else {
CopyMem (
&IkePacket->RemotePeerIp,
NTOHLLL (&EndPoint->RemoteAddr.v6),
sizeof (EFI_IPv6_ADDRESS)
);
}
//
// Try to open udp io for output if hasn't.
//
Status = IkeOpenOutputUdp (UdpService, &IkePacket->RemotePeerIp);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
IkeHdr = IkePacket->Header;
//
// Determine the IKE exchange instance by the IKE version in IKE header.
//
if (IKE_MAJOR_VERSION (IkeHdr->Version) == 2) {
Exchange = mIkeExchange[IKE_MAJOR_VERSION (IkeHdr->Version) - 1];
} else {
goto ON_EXIT;
}
switch (IkeHdr->ExchangeType) {
case IKE_XCG_TYPE_IDENTITY_PROTECT:
case IKE_XCG_TYPE_SA_INIT:
case IKE_XCG_TYPE_AUTH:
Exchange->HandleSa (UdpService, IkePacket);
break;
case IKE_XCG_TYPE_QM:
case IKE_XCG_TYPE_CREATE_CHILD_SA:
Exchange->HandleChildSa (UdpService, IkePacket);
break;
case IKE_XCG_TYPE_INFO:
case IKE_XCG_TYPE_INFO2:
Exchange->HandleInfo (UdpService, IkePacket);
break;
default:
break;
}
ON_EXIT:
if (IkePacket != NULL) {
IkePacketFree (IkePacket);
}
if (Packet != NULL) {
NetbufFree (Packet);
}
UdpIoRecvDatagram (UdpService->Input, IkeDispatch, UdpService, 0);
return ;
}
/**
Delete all established IKE SAs and related Child SAs.
This function is the subfunction of the IpSecCleanupAllSa(). It first calls
IkeDeleteChildSa() to delete all Child SAs then send out the related
Information packet.
@param[in] Private Pointer of the IPSEC_PRIVATE_DATA
**/
VOID
IkeDeleteAllSas (
IN IPSEC_PRIVATE_DATA *Private
)
{
LIST_ENTRY *Entry;
LIST_ENTRY *NextEntry;
IKEV2_SA_SESSION *Ikev2SaSession;
UINT8 Value;
EFI_STATUS Status;
IKE_EXCHANGE_INTERFACE *Exchange;
UINT8 IkeVersion;
Exchange = NULL;
//
// If the IKEv1 is supported, first deal with the Ikev1Estatblished list.
//
//
// If IKEv2 SAs are under establishing, delete it directly.
//
if (!IsListEmpty (&Private->Ikev2SessionList)) {
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->Ikev2SessionList) {
Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);
RemoveEntryList (Entry);
Ikev2SaSessionFree (Ikev2SaSession);
}
}
//
// If there is no existing established IKE SA, set the Ipsec DisableFlag to TRUE
// and turn off the IsIPsecDisabling flag.
//
if (IsListEmpty (&Private->Ikev2EstablishedList)) {
Value = IPSEC_STATUS_DISABLED;
Status = gRT->SetVariable (
IPSECCONFIG_STATUS_NAME,
&gEfiIpSecConfigProtocolGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (Value),
&Value
);
if (!EFI_ERROR (Status)) {
Private->IpSec.DisabledFlag = TRUE;
Private->IsIPsecDisabling = FALSE;
return ;
}
}
//
// Delete established IKEv2 SAs.
//
if (!IsListEmpty (&Private->Ikev2EstablishedList)) {
for (Entry = Private->Ikev2EstablishedList.ForwardLink; Entry != &Private->Ikev2EstablishedList;) {
Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);
Entry = Entry->ForwardLink;
Ikev2SaSession->SessionCommon.State = IkeStateSaDeleting;
//
// Call for Information Exchange.
//
IkeVersion = IkeGetVersionFromSession ((UINT8*)Ikev2SaSession);
if (IkeVersion == 2) {
Exchange = mIkeExchange[IkeVersion - 1];
Exchange->NegotiateInfo((UINT8*)Ikev2SaSession, NULL);
}
}
}
}

View File

@ -0,0 +1,254 @@
/** @file
Prototypes definitions of IKE service.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IKE_SERVICE_H_
#define _IKE_SERVICE_H_
#include "Ike.h"
#include "IpSecImpl.h"
#include "IkeCommon.h"
#define IPSEC_CRYPTO_LIB_MEMORY 128 * 1024
/**
This is prototype definition of general interface to intialize a IKE negotiation.
@param[in] UdpService Point to Udp Servcie used for the IKE packet sending.
@param[in] SpdEntry Point to SPD entry related to this IKE negotiation.
@param[in] PadEntry Point to PAD entry related to this IKE negotiation.
@param[in] RemoteIp Point to IP Address which the remote peer to negnotiate.
@retval EFI_SUCCESS The operation is successful.
@return Otherwise The operation is failed.
**/
typedef
EFI_STATUS
(*IKE_NEGOTIATE_SA) (
IN IKE_UDP_SERVICE * UdpService,
IN IPSEC_SPD_ENTRY * SpdEntry,
IN IPSEC_PAD_ENTRY * PadEntry,
IN EFI_IP_ADDRESS * RemoteIp
);
/**
This is prototype definition fo general interface to start a IKE negotiation at Quick Mode.
This function will be called when the related IKE SA is existed and start to
create a Child SA.
@param[in] IkeSaSession Point to IKE SA Session related to this Negotiation.
@param[in] SpdEntry Point to SPD entry related to this Negotiation.
@param[in] Context Point to data passed from the caller.
@retval EFI_SUCCESS The operation is successful.
@retval Otherwise The operation is failed.
**/
typedef
EFI_STATUS
(*IKE_NEGOTIATE_CHILD_SA) (
IN UINT8 *IkeSaSession,
IN IPSEC_SPD_ENTRY *SpdEntry,
IN UINT8 *Context
);
/**
This is prototype definition of the general interface when initialize a Inforamtion
Exchange.
@param[in] IkeSaSession Point to IKE SA Session related to.
@param[in] Context Point to data passed from caller.
**/
typedef
EFI_STATUS
(*IKE_NEGOTIATE_INFO) (
IN UINT8 *IkeSaSession,
IN UINT8 *Context
);
/**
This is prototype definition of the general interface when recived a IKE Pakcet
for the IKE SA establishing.
@param[in] UdpService Point to UDP service used to send IKE Packet.
@param[in] IkePacket Point to received IKE packet.
**/
typedef
VOID
(*IKE_HANDLE_SA) (
IN IKE_UDP_SERVICE *UdpService,
IN IKE_PACKET *IkePacket
);
/**
This is prototyp definition of the general interface when recived a IKE Packet
xfor the Child SA establishing.
@param[in] UdpService Point to UDP service used to send IKE packet.
@param[in] IkePacket Point to received IKE packet.
**/
typedef
VOID
(*IKE_HANDLE_CHILD_SA) (
IN IKE_UDP_SERVICE *UdpService,
IN IKE_PACKET *IkePacket
);
/**
This is prototype definition of the general interface when received a IKE
information Packet.
@param[in] UdpService Point to UDP service used to send IKE packet.
@param[in] IkePacket Point to received IKE packet.
**/
typedef
VOID
(*IKE_HANDLE_INFO) (
IN IKE_UDP_SERVICE *UdpService,
IN IKE_PACKET *IkePacket
);
typedef struct _IKE_EXCHANGE_INTERFACE {
UINT8 IkeVer;
IKE_NEGOTIATE_SA NegotiateSa;
IKE_NEGOTIATE_CHILD_SA NegotiateChildSa;
IKE_NEGOTIATE_INFO NegotiateInfo;
IKE_HANDLE_SA HandleSa;
IKE_HANDLE_CHILD_SA HandleChildSa;
IKE_HANDLE_INFO HandleInfo;
} IKE_EXCHANGE_INTERFACE;
/**
Open and configure a UDPIO of Udp4 for IKE packet receiving.
This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and
a UDP4 IO for each NIC handle.
@param[in] Private Point to IPSEC_PRIVATE_DATA
@param[in] Controller Handler for NIC card.
@retval EFI_SUCCESS The Operation is successful.
@retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
**/
EFI_STATUS
IkeOpenInputUdp4 (
IN IPSEC_PRIVATE_DATA *Private,
IN EFI_HANDLE Controller
);
/**
Open and configure a UDPIO of Udp6 for IKE packet receiving.
This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6
IO for each NIC handle.
@param[in] Private Point to IPSEC_PRIVATE_DATA
@param[in] Controller Handler for NIC card.
@retval EFI_SUCCESS The Operation is successful.
@retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
**/
EFI_STATUS
IkeOpenInputUdp6 (
IN IPSEC_PRIVATE_DATA *Private,
IN EFI_HANDLE Controller
);
/**
The general interface of starting IPsec Key Exchange.
This function is called when start a IKE negotiation to get a Key.
@param[in] UdpService Point to IKE_UDP_SERVICE which will be used for
IKE packet sending.
@param[in] SpdEntry Point to the SPD entry related to the IKE negotiation.
@param[in] RemoteIp Point to EFI_IP_ADDRESS related to the IKE negotiation.
@retval EFI_SUCCESS The Operation is successful.
@retval EFI_ACCESS_DENIED No related PAD entry was found.
**/
EFI_STATUS
IkeNegotiate (
IN IKE_UDP_SERVICE *UdpService,
IN IPSEC_SPD_ENTRY *SpdEntry,
IN EFI_IP_ADDRESS *RemoteIp
);
/**
The general interface when receive a IKE packet.
This function is called when UDP IO receives a IKE packet.
@param[in] Packet Point to received IKE packet.
@param[in] EndPoint Point to UDP_END_POINT which contains the information of
Remote IP and Port.
@param[in] IoStatus The Status of Recieve Token.
@param[in] Context Point to data passed from the caller.
**/
VOID
IkeDispatch (
IN NET_BUF *Packet,
IN UDP_END_POINT *EndPoint,
IN EFI_STATUS IoStatus,
IN VOID *Context
);
/**
Check if the NIC handle is binded to a Udp service.
@param[in] Private Pointer of IPSEC_PRIVATE_DATA
@param[in] NicHandle The Handle of the NIC card
@param[in] IpVersion The version of the IP stack.
@return a pointer of IKE_UDP_SERVICE.
**/
IKE_UDP_SERVICE *
IkeLookupUdp (
IN IPSEC_PRIVATE_DATA *Private,
IN EFI_HANDLE Handle,
IN UINT8 IpVersion
);
/**
Delete all established IKE SAs and related Child SAs.
This function is the subfunction of the IpSecCleanupAllSa(). It first calls
IkeDeleteChildSa() to delete all Child SAs then send out the related
Information packet.
@param[in] Private Pointer of the IPSEC_PRIVATE_DATA.
**/
VOID
IkeDeleteAllSas (
IN IPSEC_PRIVATE_DATA *Private
);
extern IKE_EXCHANGE_INTERFACE mIkev1Exchange;
extern IKE_EXCHANGE_INTERFACE mIkev2Exchange;
#endif

View File

@ -0,0 +1,192 @@
/** @file
The operations for Child SA.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Utility.h"
/**
Generate IKE Packet for CREATE_CHILD_SA exchange.
This IKE Packet would be the packet for creating new CHILD SA, or the packet for
rekeying existing IKE SA, or the packet for existing CHILD SA.
@param[in] SaSession Pointer to related SA session.
@param[in] Context The data passed by the caller.
return a pointer of IKE packet.
**/
IKE_PACKET *
Ikev2CreateChildGenerator (
IN UINT8 *SaSession,
IN VOID *Context
)
{
IKEV2_CHILD_SA_SESSION *ChildSaSession;
IKEV2_SA_SESSION *IkeSaSession;
IKE_PACKET *IkePacket;
IKE_PAYLOAD *NotifyPayload;
UINT32 *MessageId;
ChildSaSession = (IKEV2_CHILD_SA_SESSION *) SaSession;
IkePacket = IkePacketAlloc();
MessageId = NULL;
if (IkePacket == NULL) {
return NULL;
}
if (ChildSaSession == NULL) {
return NULL;
}
if (Context != NULL) {
MessageId = (UINT32 *) Context;
}
IkePacket->Header->Version = (UINT8) (2 << 4);
IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_NOTIFY;
IkePacket->Header->ExchangeType = IKE_XCG_TYPE_CREATE_CHILD_SA;
if (ChildSaSession->SessionCommon.IkeSessionType == IkeSessionTypeChildSa) {
//
// 1.a Fill the IkePacket->Hdr
//
IkePacket->Header->InitiatorCookie = ChildSaSession->IkeSaSession->InitiatorCookie;
IkePacket->Header->ResponderCookie = ChildSaSession->IkeSaSession->ResponderCookie;
if (MessageId != NULL) {
IkePacket->Header->MessageId = *MessageId;
} else {
IkePacket->Header->MessageId = ChildSaSession->MessageId;
}
if (ChildSaSession->SessionCommon.IsInitiator) {
IkePacket->Header->Flags = IKE_HEADER_FLAGS_CHILD_INIT;
} else {
IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;
}
} else {
IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
//
// 1.a Fill the IkePacket->Hdr
//
IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;
IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;
if (MessageId != NULL) {
IkePacket->Header->MessageId = *MessageId;
} else {
IkePacket->Header->MessageId = IkeSaSession->MessageId;
}
if (IkeSaSession->SessionCommon.IsInitiator) {
IkePacket->Header->Flags = IKE_HEADER_FLAGS_CHILD_INIT;
} else {
IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;
}
}
//
// According to RFC4306, Chapter 4.
// A minimal implementation may support the CREATE_CHILD_SA exchange only to
// recognize requests and reject them with a Notify payload of type NO_ADDITIONAL_SAS.
//
NotifyPayload = Ikev2GenerateNotifyPayload (
0,
IKEV2_PAYLOAD_TYPE_NONE,
0,
IKEV2_NOTIFICATION_NO_ADDITIONAL_SAS,
NULL,
NULL,
0
);
IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload);
//
// TODO: Support the CREATE_CHILD_SA exchange.
//
return IkePacket;
}
/**
Parse the IKE packet of CREATE_CHILD_SA exchange.
This function parse the IKE packet and save the related information to further
calculation.
@param[in] SaSession Pointer to IKEv2_CHILD_SA_SESSION related to this Exchange.
@param[in] IkePacket Received packet to be parsed.
@retval EFI_SUCCESS The IKE Packet is acceptable.
@retval EFI_UNSUPPORTED Not support the CREATE_CHILD_SA request.
**/
EFI_STATUS
Ikev2CreateChildParser (
IN UINT8 *SaSession,
IN IKE_PACKET *IkePacket
)
{
return EFI_UNSUPPORTED;
}
/**
Routine process before the payload decoding.
@param[in] SessionCommon Pointer to ChildSa SessionCommon.
@param[in] PayloadBuf Pointer to the payload.
@param[in] PayloadSize Size of PayloadBuf in byte.
@param[in] PayloadType Type of Payload.
**/
VOID
Ikev2ChildSaBeforeDecodePayload (
IN UINT8 *SessionCommon,
IN UINT8 *PayloadBuf,
IN UINTN PayloadSize,
IN UINT8 PayloadType
)
{
}
/**
Routine Process after the payload encoding.
@param[in] SessionCommon Pointer to ChildSa SessionCommon.
@param[in] PayloadBuf Pointer to the payload.
@param[in] PayloadSize Size of PayloadBuf in byte.
@param[in] PayloadType Type of Payload.
**/
VOID
Ikev2ChildSaAfterEncodePayload (
IN UINT8 *SessionCommon,
IN UINT8 *PayloadBuf,
IN UINTN PayloadSize,
IN UINT8 PayloadType
)
{
}
IKEV2_PACKET_HANDLER mIkev2CreateChild = {
//
// Create Child
//
Ikev2CreateChildParser,
Ikev2CreateChildGenerator
};

View File

@ -0,0 +1,803 @@
/** @file
The general interfaces of the IKEv2.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Utility.h"
#include "IpSecDebug.h"
#include "IkeService.h"
#include "IpSecConfigImpl.h"
/**
General interface to intialize a IKEv2 negotiation.
@param[in] UdpService Point to Udp Servcie used for the IKE packet sending.
@param[in] SpdEntry Point to SPD entry related to this IKE negotiation.
@param[in] PadEntry Point to PAD entry related to this IKE negotiation.
@param[in] RemoteIp Point to IP Address which the remote peer to negnotiate.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated.
@retval EFI_INVALID_PARAMETER If UdpService or RemoteIp is NULL.
@return Others The operation is failed.
**/
EFI_STATUS
Ikev2NegotiateSa (
IN IKE_UDP_SERVICE *UdpService,
IN IPSEC_SPD_ENTRY *SpdEntry,
IN IPSEC_PAD_ENTRY *PadEntry,
IN EFI_IP_ADDRESS *RemoteIp
)
{
IPSEC_PRIVATE_DATA *Private;
IKEV2_SA_SESSION *IkeSaSession;
IKEV2_SESSION_COMMON *SessionCommon;
IKEV2_PACKET_HANDLER Handler;
IKE_PACKET *IkePacket;
EFI_STATUS Status;
if (UdpService == NULL || RemoteIp == NULL) {
return EFI_INVALID_PARAMETER;
}
IkePacket = NULL;
Private = (UdpService->IpVersion == IP_VERSION_4) ?
IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);
//
// Lookup the remote ip address in the processing IKE SA session list.
//
IkeSaSession = Ikev2SaSessionLookup (&Private->Ikev2SessionList, RemoteIp);
if (IkeSaSession != NULL) {
//
// Drop the packet if already in process.
//
return EFI_SUCCESS;
}
//
// Create a new IkeSaSession and initiate the common parameters.
//
IkeSaSession = Ikev2SaSessionAlloc (Private, UdpService);
if (IkeSaSession == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Set the specific parameters and state(IKE_STATE_INIT).
//
IkeSaSession->Spd = SpdEntry;
IkeSaSession->Pad = PadEntry;
SessionCommon = &IkeSaSession->SessionCommon;
SessionCommon->IsInitiator = TRUE;
SessionCommon->State = IkeStateInit;
//
// TODO: Get the prefer DH Group from the IPsec Configuration, after the IPsecconfig application update
// to support it.
//
SessionCommon->PreferDhGroup = IKEV2_TRANSFORM_ID_DH_1024MODP;
CopyMem (
&SessionCommon->RemotePeerIp,
RemoteIp,
sizeof (EFI_IP_ADDRESS)
);
CopyMem (
&SessionCommon->LocalPeerIp,
&UdpService->DefaultAddress,
sizeof (EFI_IP_ADDRESS)
);
IKEV2_DUMP_STATE (SessionCommon->State, IkeStateInit);
//
// Initiate the SAD data of the IkeSaSession.
//
IkeSaSession->SaData = Ikev2InitializeSaData (SessionCommon);
if (IkeSaSession->SaData == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
//
// Generate an IKE request packet and send it out.
//
Handler = mIkev2Initial[IkeSaSession->Pad->Data->AuthMethod][SessionCommon->State];
IkePacket = Handler.Generator ((UINT8 *) IkeSaSession, NULL);
if (IkePacket == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
Status = Ikev2SendIkePacket (UdpService, (UINT8 *) SessionCommon, IkePacket, 0);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Insert the current IkeSaSession into the processing IKE SA list.
//
Ikev2SaSessionInsert (&Private->Ikev2SessionList, IkeSaSession, RemoteIp);
return EFI_SUCCESS;
ON_ERROR:
if (IkePacket != NULL) {
IkePacketFree (IkePacket);
}
Ikev2SaSessionFree (IkeSaSession);
return Status;
}
/**
It is general interface to negotiate the Child SA.
There are three situations which will invoke this function. First, create a CHILD
SA if the input Context is NULL. Second, rekeying the existing IKE SA if the Context
is a IKEv2_SA_SESSION. Third, rekeying the existing CHILD SA if the context is a
IKEv2_CHILD_SA_SESSION.
@param[in] IkeSaSession Pointer to IKEv2_SA_SESSION related to this operation.
@param[in] SpdEntry Pointer to IPSEC_SPD_ENTRY related to this operation.
@param[in] Context The data pass from the caller.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated.
@retval EFI_UNSUPPORTED The condition is not support yet.
@return Others The operation is failed.
**/
EFI_STATUS
Ikev2NegotiateChildSa (
IN UINT8 *IkeSaSession,
IN IPSEC_SPD_ENTRY *SpdEntry,
IN UINT8 *Context
)
{
EFI_STATUS Status;
IKEV2_SA_SESSION *SaSession;
IKEV2_CHILD_SA_SESSION *ChildSaSession;
IKEV2_SESSION_COMMON *ChildSaCommon;
IKE_PACKET *IkePacket;
IKE_UDP_SERVICE *UdpService;
SaSession = (IKEV2_SA_SESSION*) IkeSaSession;
UdpService = SaSession->SessionCommon.UdpService;
IkePacket = NULL;
//
// 1. Create another child SA session if context is null.
// 2. Rekeying the IKE SA session if the context is IKE SA session.
// 3. Rekeying the child SA session if the context is child SA session.
//
if (Context == NULL) {
//
// Create a new ChildSaSession and initiate the common parameters.
//
ChildSaSession = Ikev2ChildSaSessionAlloc (UdpService, SaSession);
if (ChildSaSession == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Set the specific parameters and state as IKE_STATE_CREATE_CHILD.
//
ChildSaSession->Spd = SpdEntry;
ChildSaCommon = &ChildSaSession->SessionCommon;
ChildSaCommon->IsInitiator = TRUE;
ChildSaCommon->State = IkeStateCreateChild;
IKEV2_DUMP_STATE (ChildSaCommon->State, IkeStateCreateChild);
if (SpdEntry->Selector->NextLayerProtocol != EFI_IPSEC_ANY_PROTOCOL) {
ChildSaSession->ProtoId = SpdEntry->Selector->NextLayerProtocol;
}
if (SpdEntry->Selector->LocalPort != EFI_IPSEC_ANY_PORT) {
ChildSaSession->LocalPort = SpdEntry->Selector->LocalPort;
}
if (SpdEntry->Selector->RemotePort != EFI_IPSEC_ANY_PORT) {
ChildSaSession->RemotePort = SpdEntry->Selector->RemotePort;
}
//
// Initiate the SAD data parameters of the ChildSaSession.
//
ChildSaSession->SaData = Ikev2InitializeSaData (ChildSaCommon);
if (ChildSaSession->SaData == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
//
// Generate an IKE request packet and send it out.
//
IkePacket = mIkev2CreateChild.Generator ((UINT8 *) ChildSaSession, NULL);
if (IkePacket == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
Status = Ikev2SendIkePacket (UdpService, (UINT8 *) ChildSaCommon, IkePacket, 0);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Insert the ChildSaSession into processing child SA list.
//
Ikev2ChildSaSessionInsert (&SaSession->ChildSaSessionList, ChildSaSession);
} else {
//
// TODO: Rekeying IkeSaSession or ChildSaSession, NOT support yet.
//
// Rekey IkeSa, set IkeSaSession->State and pass over IkeSaSession
// Rekey ChildSa, set ChildSaSession->State and pass over ChildSaSession
//
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
ON_ERROR:
if (ChildSaSession->SaData != NULL) {
FreePool (ChildSaSession->SaData);
}
if (ChildSaSession->SessionCommon.TimeoutEvent != NULL) {
gBS->CloseEvent (ChildSaSession->SessionCommon.TimeoutEvent);
}
if (IkePacket != NULL) {
IkePacketFree (IkePacket);
}
Ikev2ChildSaSessionFree (ChildSaSession);
return Status;
}
/**
It is general interface to start the Information Exchange.
There are three situations which will invoke this function. First, deliver a Delete Information
to delete the IKE SA if the input Context is NULL and the state of related IkeSaSeesion's is on
deleting.Second, deliver a Notify Information without the contents if the input Context is NULL.
Third, deliver a Notify Information if the input Context is not NULL.
@param[in] IkeSaSession Pointer to IKEv2_SA_SESSION related to this operation.
@param[in] Context Data passed by caller.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated.
@retval EFI_UNSUPPORTED The condition is not support yet.
@return Otherwise The operation is failed.
**/
EFI_STATUS
Ikev2NegotiateInfo (
IN UINT8 *IkeSaSession,
IN UINT8 *Context
)
{
EFI_STATUS Status;
IKEV2_SA_SESSION *Ikev2SaSession;
IKEV2_CHILD_SA_SESSION *ChildSaSession;
IKEV2_SESSION_COMMON *SaCommon;
IKE_PACKET *IkePacket;
IKE_UDP_SERVICE *UdpService;
LIST_ENTRY *Entry;
LIST_ENTRY *NextEntry;
Ikev2SaSession = (IKEV2_SA_SESSION *) IkeSaSession;
UdpService = Ikev2SaSession->SessionCommon.UdpService;
SaCommon = &Ikev2SaSession->SessionCommon;
IkePacket = NULL;
Status = EFI_SUCCESS;
//
// Delete the IKE SA.
//
if (Ikev2SaSession->SessionCommon.State == IkeStateSaDeleting && Context == NULL) {
//
// The IKE SA Session should be initiator if it triggers the deleting.
//
Ikev2SaSession->SessionCommon.IsInitiator = TRUE;
//
// Generate Information Packet which contains the Delete Payload.
//
IkePacket = mIkev2Info.Generator ((UINT8 *) Ikev2SaSession, NULL);
if (IkePacket == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
//
// Send out the Packet
//
Status = Ikev2SendIkePacket (UdpService, (UINT8 *) SaCommon, IkePacket, 0);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
} else if (!IsListEmpty (&Ikev2SaSession->DeleteSaList)) {
//
// Iterate all Deleting Child SAs.
//
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Ikev2SaSession->DeleteSaList) {
ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_DEL_SA (Entry);
ChildSaSession->SessionCommon.State = IkeStateSaDeleting;
//
// Generate Information Packet which contains the Child SA Delete Payload.
//
IkePacket = mIkev2Info.Generator ((UINT8 *) ChildSaSession, NULL);
if (IkePacket == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
//
// Send out the Packet
//
Status = Ikev2SendIkePacket (UdpService, (UINT8 *) &ChildSaSession->SessionCommon, IkePacket, 0);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
}
} else if (Context == NULL) {
//
// TODO: Deliver null notification message.
//
} else if (Context != NULL) {
//
// TODO: Send out the Information Exchange which contains the Notify Payload.
//
}
ON_ERROR:
if (IkePacket != NULL) {
IkePacketFree (IkePacket);
}
return Status;
}
/**
The general interface when received a IKEv2 packet for the IKE SA establishing.
This function first find the related IKE SA Session according to the IKE packet's
remote IP. Then call the corresponding function to handle this IKE packet according
to the related IKE SA Session's State.
@param[in] UdpService Pointer of related UDP Service.
@param[in] IkePacket Data passed by caller.
**/
VOID
Ikev2HandleSa (
IN IKE_UDP_SERVICE *UdpService,
IN IKE_PACKET *IkePacket
)
{
EFI_STATUS Status;
IKEV2_SA_SESSION *IkeSaSession;
IKEV2_CHILD_SA_SESSION *ChildSaSession;
IKEV2_SESSION_COMMON *IkeSaCommon;
IKEV2_SESSION_COMMON *ChildSaCommon;
IKEV2_PACKET_HANDLER Handler;
IKE_PACKET *Reply;
IPSEC_PAD_ENTRY *PadEntry;
IPSEC_PRIVATE_DATA *Private;
BOOLEAN IsNewSession;
Private = (UdpService->IpVersion == IP_VERSION_4) ?
IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);
ChildSaSession = NULL;
ChildSaCommon = NULL;
//
// Lookup the remote ip address in the processing IKE SA session list.
//
IkeSaSession = Ikev2SaSessionLookup (&Private->Ikev2SessionList, &IkePacket->RemotePeerIp);
IsNewSession = FALSE;
if (IkeSaSession == NULL) {
//
// Lookup the remote ip address in the pad.
//
PadEntry = IpSecLookupPadEntry (UdpService->IpVersion, &IkePacket->RemotePeerIp);
if (PadEntry == NULL) {
//
// Drop the packet if no pad entry matched, this is the request from RFC 4301.
//
return ;
}
//
// Create a new IkeSaSession and initiate the common parameters.
//
IkeSaSession = Ikev2SaSessionAlloc (Private, UdpService);
if (IkeSaSession == NULL) {
return;
}
IkeSaSession->Pad = PadEntry;
IkeSaCommon = &IkeSaSession->SessionCommon;
IkeSaCommon->IsInitiator = FALSE;
IkeSaCommon->State = IkeStateInit;
IKEV2_DUMP_STATE (IkeSaCommon->State, IkeStateInit);
CopyMem (
&IkeSaCommon->RemotePeerIp,
&IkePacket->RemotePeerIp,
sizeof (EFI_IP_ADDRESS)
);
CopyMem (
&IkeSaCommon->LocalPeerIp,
&UdpService->DefaultAddress,
sizeof (EFI_IP_ADDRESS)
);
IsNewSession = TRUE;
}
//
// Validate the IKE packet header.
//
Status = Ikev2ValidateHeader (IkeSaSession, IkePacket->Header);
if (EFI_ERROR (Status)) {
//
// Drop the packet if invalid IKE header.
//
goto ON_ERROR;
}
//
// Decode all the payloads in the IKE packet.
//
IkeSaCommon = &IkeSaSession->SessionCommon;
Status = Ikev2DecodePacket (IkeSaCommon, IkePacket, IkeSessionTypeIkeSa);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Try to reate the first ChildSa Session of that IkeSaSession.
// If the IkeSaSession is responder, here will create the first ChildSaSession.
//
if (IkeSaCommon->State == IkeStateAuth && IsListEmpty(&IkeSaSession->ChildSaSessionList)) {
//
// Generate a piggyback child SA in IKE_STATE_AUTH state.
//
ASSERT (IsListEmpty (&IkeSaSession->ChildSaSessionList) &&
IsListEmpty (&IkeSaSession->ChildSaEstablishSessionList));
ChildSaSession = Ikev2ChildSaSessionCreate (IkeSaSession, UdpService);
ChildSaCommon = &ChildSaSession->SessionCommon;
}
//
// Parse the IKE request packet according to the auth method and current state.
//
Handler = mIkev2Initial[IkeSaSession->Pad->Data->AuthMethod][IkeSaCommon->State];
Status = Handler.Parser ((UINT8 *)IkeSaSession, IkePacket);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Try to reate the first ChildSa Session of that IkeSaSession.
// If the IkeSaSession is initiator, here will create the first ChildSaSession.
//
if (IkeSaCommon->State == IkeStateAuth && IsListEmpty(&IkeSaSession->ChildSaSessionList)) {
//
// Generate a piggyback child SA in IKE_STATE_AUTH state.
//
ASSERT (IsListEmpty (&IkeSaSession->ChildSaSessionList) &&
IsListEmpty (&IkeSaSession->ChildSaEstablishSessionList));
ChildSaSession = Ikev2ChildSaSessionCreate (IkeSaSession, UdpService);
ChildSaCommon = &ChildSaSession->SessionCommon;
//
// Initialize the SA data for Child SA.
//
ChildSaSession->SaData = Ikev2InitializeSaData (ChildSaCommon);
}
//
// Generate the IKE response packet and send it out if not established.
//
if (IkeSaCommon->State != IkeStateIkeSaEstablished) {
Handler = mIkev2Initial[IkeSaSession->Pad->Data->AuthMethod][IkeSaCommon->State];
Reply = Handler.Generator ((UINT8 *) IkeSaSession, NULL);
if (Reply == NULL) {
goto ON_ERROR;
}
Status = Ikev2SendIkePacket (UdpService, (UINT8 *) IkeSaCommon, Reply, 0);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
if (!IkeSaCommon->IsInitiator) {
IkeSaCommon->State ++;
IKEV2_DUMP_STATE (IkeSaCommon->State - 1, IkeSaCommon->State);
}
}
//
// Insert the new IkeSaSession into the Private processing IkeSaSession List.
//
if (IsNewSession) {
Ikev2SaSessionInsert (&Private->Ikev2SessionList, IkeSaSession, &IkePacket->RemotePeerIp);
}
//
// Register the IkeSaSession and remove it from processing list.
//
if (IkeSaCommon->State == IkeStateIkeSaEstablished) {
//
// Remove the Established IKE SA Session from the IKE SA Session Negotiating list
// and insert it into IKE SA Session Established list.
//
Ikev2SaSessionRemove (&Private->Ikev2SessionList, &IkePacket->RemotePeerIp);
Ikev2SaSessionReg (IkeSaSession, Private);
//
// Remove the Established Child SA Session from the IkeSaSession->ChildSaSessionList
// ,insert it into IkeSaSession->ChildSaEstablishSessionList and save this Child SA
// into SAD.
//
ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (IkeSaSession->ChildSaSessionList.BackLink);
Ikev2ChildSaSessionRemove (
&IkeSaSession->ChildSaSessionList,
ChildSaSession->LocalPeerSpi,
IKEV2_ESTABLISHING_CHILDSA_LIST
);
Ikev2ChildSaSessionReg (ChildSaSession, Private);
}
return ;
ON_ERROR:
if (ChildSaSession != NULL) {
//
// Remove the ChildSa from the list (Established list or Negotiating list).
//
RemoveEntryList (&ChildSaSession->ByIkeSa);
Ikev2ChildSaSessionFree (ChildSaSession);
}
if (IsNewSession && IkeSaSession != NULL) {
//
// Remove the IkeSa from the list (Established list or Negotiating list).
//
if ((&IkeSaSession->BySessionTable)->ForwardLink != NULL &&
!IsListEmpty (&IkeSaSession->BySessionTable
)){
RemoveEntryList (&IkeSaSession->BySessionTable);
}
Ikev2SaSessionFree (IkeSaSession);
}
return ;
}
/**
The general interface when received a IKEv2 packet for the IKE Child SA establishing
or IKE SA/CHILD SA rekeying.
This function first find the related IKE SA Session according to the IKE packet's
remote IP. Then call the corresponding function to handle this IKE packet according
to the related IKE Child Session's State.
@param[in] UdpService Pointer of related UDP Service.
@param[in] IkePacket Data passed by caller.
**/
VOID
Ikev2HandleChildSa (
IN IKE_UDP_SERVICE *UdpService,
IN IKE_PACKET *IkePacket
)
{
EFI_STATUS Status;
IKEV2_SA_SESSION *IkeSaSession;
IKEV2_CREATE_CHILD_REQUEST_TYPE RequestType;
IKE_PACKET *Reply;
IPSEC_PRIVATE_DATA *Private;
Private = (UdpService->IpVersion == IP_VERSION_4) ?
IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);
Reply = NULL;
//
// Lookup the remote ip address in the processing IKE SA session list.
//
IkeSaSession = Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, &IkePacket->RemotePeerIp);
if (IkeSaSession == NULL) {
//
// Drop the packet if no IKE SA associated.
//
return ;
}
//
// Validate the IKE packet header.
//
if (!Ikev2ValidateHeader (IkeSaSession, IkePacket->Header)) {
//
// Drop the packet if invalid IKE header.
//
return;
}
//
// Decode all the payloads in the IKE packet.
//
Status = Ikev2DecodePacket (&IkeSaSession->SessionCommon, IkePacket, IkeSessionTypeIkeSa);
if (EFI_ERROR (Status)) {
return;
}
//
// Get the request type: CreateChildSa/RekeyChildSa/RekeyIkeSa.
//
RequestType = Ikev2ChildExchangeRequestType (IkePacket);
switch (RequestType) {
case IkeRequestTypeCreateChildSa:
case IkeRequestTypeRekeyChildSa:
case IkeRequestTypeRekeyIkeSa:
//
// Parse the IKE request packet. Not support CREATE_CHILD_SA exchange yet, so
// only EFI_UNSUPPORTED will be returned and that will trigger a reply with a
// Notify payload of type NO_ADDITIONAL_SAS.
//
Status = mIkev2CreateChild.Parser ((UINT8 *) IkeSaSession, IkePacket);
if (EFI_ERROR (Status)) {
goto ON_REPLY;
}
default:
//
// No support.
//
return ;
}
ON_REPLY:
//
// Generate the reply packet if needed and send it out.
//
if (IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) {
Reply = mIkev2CreateChild.Generator ((UINT8 *) IkeSaSession, &IkePacket->Header->MessageId);
if (Reply != NULL) {
Status = Ikev2SendIkePacket (UdpService, (UINT8 *) &(IkeSaSession->SessionCommon), Reply, 0);
if (EFI_ERROR (Status)) {
//
// Delete Reply payload.
//
if (Reply != NULL) {
IkePacketFree (Reply);
}
}
}
}
return ;
}
/**
It is general interface to handle IKEv2 information Exchange.
@param[in] UdpService Point to IKE UPD Service related to this information exchange.
@param[in] IkePacket The IKE packet to be parsed.
**/
VOID
Ikev2HandleInfo (
IN IKE_UDP_SERVICE *UdpService,
IN IKE_PACKET *IkePacket
)
{
EFI_STATUS Status;
IKEV2_SESSION_COMMON *SessionCommon;
IKEV2_SA_SESSION *IkeSaSession;
IPSEC_PRIVATE_DATA *Private;
Private = (UdpService->IpVersion == IP_VERSION_4) ?
IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);
//
// Lookup the remote ip address in the processing IKE SA session list.
//
IkeSaSession = Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, &IkePacket->RemotePeerIp);
if (IkeSaSession == NULL) {
//
// Drop the packet if no IKE SA associated.
//
return ;
}
//
// Validate the IKE packet header.
//
if (!Ikev2ValidateHeader (IkeSaSession, IkePacket->Header)) {
//
// Drop the packet if invalid IKE header.
//
return;
}
SessionCommon = &IkeSaSession->SessionCommon;
//
// Decode all the payloads in the IKE packet.
//
Status = Ikev2DecodePacket (SessionCommon, IkePacket, IkeSessionTypeIkeSa);
if (EFI_ERROR (Status)) {
return;
}
Status = mIkev2Info.Parser ((UINT8 *)IkeSaSession, IkePacket);
if (EFI_ERROR (Status)) {
//
// Drop the packet if fail to parse.
//
return;
}
}
IKE_EXCHANGE_INTERFACE mIkev1Exchange = {
1,
NULL, //Ikev1NegotiateSa
NULL, //Ikev1NegotiateChildSa
NULL,
NULL, //Ikev1HandleSa,
NULL, //Ikev1HandleChildSa
NULL, //Ikev1HandleInfo
};
IKE_EXCHANGE_INTERFACE mIkev2Exchange = {
2,
Ikev2NegotiateSa,
Ikev2NegotiateChildSa,
Ikev2NegotiateInfo,
Ikev2HandleSa,
Ikev2HandleChildSa,
Ikev2HandleInfo
};

View File

@ -0,0 +1,258 @@
/** @file
IKEv2 related definitions.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IKE_V2_H_
#define _IKE_V2_H_
#include "Ike.h"
#include "Payload.h"
#define IKEV2_TS_ANY_PORT 0xffff
#define IKEV2_TS_ANY_PROTOCOL 0
#define IKEV2_DELET_CHILDSA_LIST 0
#define IKEV2_ESTABLISHING_CHILDSA_LIST 1
#define IKEV2_ESTABLISHED_CHILDSA_LIST 2
#define IKEV2_SA_SESSION_SIGNATURE SIGNATURE_32 ('I', 'K', 'E', 'I')
#define IKEV2_SA_SESSION_FROM_COMMON(a) CR (a, IKEV2_SA_SESSION, SessionCommon, IKEV2_SA_SESSION_SIGNATURE)
#define IKEV2_SA_SESSION_BY_SESSION(a) CR (a, IKEV2_SA_SESSION, BySessionTable, IKEV2_SA_SESSION_SIGNATURE)
#define IKEV2_SA_SESSION_BY_ESTABLISHED(a) CR (a, IKEV2_SA_SESSION, ByEstablishedTable, IKEV2_SA_SESSION_SIGNATURE)
#define IKEV2_CHILD_SA_SESSION_SIGNATURE SIGNATURE_32 ('I', 'K', 'E', 'C')
#define IKEV2_CHILD_SA_SESSION_FROM_COMMON(a) CR (a, IKEV2_CHILD_SA_SESSION, SessionCommon, IKEV2_CHILD_SA_SESSION_SIGNATURE)
#define IKEV2_CHILD_SA_SESSION_BY_IKE_SA(a) CR (a, IKEV2_CHILD_SA_SESSION, ByIkeSa, IKEV2_CHILD_SA_SESSION_SIGNATURE)
#define IKEV2_CHILD_SA_SESSION_BY_DEL_SA(a) CR (a, IKEV2_CHILD_SA_SESSION, ByDelete, IKEV2_CHILD_SA_SESSION_SIGNATURE)
#define IS_IKEV2_SA_SESSION(s) ((s)->Common.IkeSessionType == IkeSessionTypeIkeSa)
#define IKEV2_SA_FIRST_PROPOSAL(Sa) (IKEV2_PROPOSAL *)((IKEV2_SA *)(Sa)+1)
#define IKEV2_NEXT_TRANSFORM_WITH_SIZE(Transform,TransformSize) \
(IKEV2_TRANSFORM *) ((UINT8 *)(Transform) + (TransformSize))
#define IKEV2_NEXT_PROPOSAL_WITH_SIZE(Proposal, ProposalSize) \
(IKEV2_PROPOSAL *) ((UINT8 *)(Proposal) + (ProposalSize))
#define IKEV2_PROPOSAL_FIRST_TRANSFORM(Proposal) \
(IKEV2_TRANSFORM *)((UINT8 *)((IKEV2_PROPOSAL *)(Proposal)+1) + \
(((IKEV2_PROPOSAL *)(Proposal))->SpiSize))
#define IKEV2_PROPOSAL_FIRST_TRANSFORM(Proposal) \
(IKEV2_TRANSFORM *)((UINT8 *)((IKEV2_PROPOSAL *)(Proposal)+1) + \
(((IKEV2_PROPOSAL *)(Proposal))->SpiSize))
typedef enum {
IkeStateInit,
IkeStateAuth,
IkeStateIkeSaEstablished,
IkeStateCreateChild,
IkeStateSaRekeying,
IkeStateChildSaEstablished,
IkeStateSaDeleting,
IkeStateMaximum
} IKEV2_SESSION_STATE;
typedef enum {
IkeRequestTypeCreateChildSa,
IkeRequestTypeRekeyChildSa,
IkeRequestTypeRekeyIkeSa,
IkeRequestTypeMaximum
} IKEV2_CREATE_CHILD_REQUEST_TYPE;
typedef struct {
UINT8 *GxBuffer;
UINTN GxSize;
UINT8 *GyBuffer;
UINTN GySize;
UINT8 *GxyBuffer;
UINTN GxySize;
UINT8 *DhContext;
} IKEV2_DH_BUFFER;
typedef struct {
IKEV2_DH_BUFFER *DhBuffer;
UINT8 *SkdKey;
UINTN SkdKeySize;
UINT8 *SkAiKey;
UINTN SkAiKeySize;
UINT8 *SkArKey;
UINTN SkArKeySize;
UINT8 *SkEiKey;
UINTN SkEiKeySize;
UINT8 *SkErKey;
UINTN SkErKeySize;
UINT8 *SkPiKey;
UINTN SkPiKeySize;
UINT8 *SkPrKey;
UINTN SkPrKeySize;
} IKEV2_SESSION_KEYS;
typedef struct {
UINT16 LifeType;
UINT64 LifeDuration;
UINT16 EncAlgId;
UINTN EnckeyLen;
UINT16 Prf;
UINT16 IntegAlgId;
UINTN IntegKeyLen;
UINT16 DhGroup;
UINT8 ExtSeq;
} IKEV2_SA_PARAMS;
//
// Internal Payload
//
typedef struct {
IKEV2_SA SaHeader;
UINTN NumProposals;
//
// IKE_PROPOSAL_DATA Proposals[1];
//
} IKEV2_SA_DATA;
typedef struct {
UINT8 ProposalIndex;
UINT8 ProtocolId;
UINT8 *Spi;
UINT8 NumTransforms;
//
// IKE_TRANSFORM_DATA Transforms[1];
//
} IKEV2_PROPOSAL_DATA;
typedef struct {
UINT8 TransformIndex;
UINT8 TransformType;
UINT16 TransformId;
IKE_SA_ATTRIBUTE Attribute;
} IKEV2_TRANSFORM_DATA;
typedef struct {
UINT8 IkeVer;
IKE_SESSION_TYPE IkeSessionType;
BOOLEAN IsInitiator;
BOOLEAN IsOnDeleting; // Flag to indicate whether the SA is on deleting.
IKEV2_SESSION_STATE State;
EFI_EVENT TimeoutEvent;
UINT64 TimeoutInterval;
UINTN RetryCount;
IKE_PACKET *LastSentPacket;
IKEV2_SA_PARAMS *SaParams;
UINT16 PreferDhGroup;
EFI_IP_ADDRESS RemotePeerIp;
EFI_IP_ADDRESS LocalPeerIp;
IKE_ON_PAYLOAD_FROM_NET BeforeDecodePayload;
IKE_ON_PAYLOAD_FROM_NET AfterEncodePayload;
IKE_UDP_SERVICE *UdpService;
IPSEC_PRIVATE_DATA *Private;
} IKEV2_SESSION_COMMON;
typedef struct {
UINT32 Signature;
IKEV2_SESSION_COMMON SessionCommon;
UINT64 InitiatorCookie;
UINT64 ResponderCookie;
//
// Initiator: SA proposals to be sent
// Responder: SA proposals to be matched
//
IKEV2_SA_DATA *SaData; // SA Private struct used for SA payload generation
IKEV2_SESSION_KEYS *IkeKeys;
UINT8 *NiBlock;
UINTN NiBlkSize;
UINT8 *NrBlock;
UINTN NrBlkSize;
UINT8 *NCookie; // Buffer Contains the Notify Cookie
UINTN NCookieSize; // Size of NCookie
IPSEC_PAD_ENTRY *Pad;
IPSEC_SPD_ENTRY *Spd; // SPD that requested the negotiation, TODO: better use SPD selector
LIST_ENTRY ChildSaSessionList;
LIST_ENTRY ChildSaEstablishSessionList; // For Establish Child SA.
LIST_ENTRY InfoMIDList; // For Information MID
LIST_ENTRY DeleteSaList; // For deteling Child SA.
UINT8 *InitPacket;
UINTN InitPacketSize;
UINT8 *RespPacket;
UINTN RespPacketSize;
UINT32 MessageId;
LIST_ENTRY BySessionTable; // Use for all IkeSaSession Links
} IKEV2_SA_SESSION;
typedef struct {
UINT32 Signature;
IKEV2_SESSION_COMMON SessionCommon;
IKEV2_SA_SESSION *IkeSaSession;
UINT32 MessageId;
IKEV2_SA_DATA *SaData;
UINT8 IpsecProtocol;
UINT32 LocalPeerSpi;
UINT32 RemotePeerSpi;
UINT8 *NiBlock;
UINTN NiBlkSize;
UINT8 *NrBlock;
UINTN NrBlkSize;
SA_KEYMATS ChildKeymats;
IKEV2_DH_BUFFER *DhBuffer; //New DH exchnaged by CREATE_CHILD_SA
IPSEC_SPD_ENTRY *Spd;
EFI_IPSEC_SPD_SELECTOR *SpdSelector;
UINT16 ProtoId;
UINT16 RemotePort;
UINT16 LocalPort;
LIST_ENTRY ByIkeSa;
LIST_ENTRY ByDelete;
} IKEV2_CHILD_SA_SESSION;
typedef enum {
Ikev2InfoNotify,
Ikev2InfoDelete,
Ikev2InfoLiveCheck
} IKEV2_INFO_TYPE;
//
// This struct is used to pass the detail infromation to the InfoGenerator() for
// the response Information Exchange Message creatation.
//
typedef struct {
UINT32 MessageId;
IKEV2_INFO_TYPE InfoType;
} IKEV2_INFO_EXCHANGE_CONTEXT;
typedef struct {
UINTN DataSize;
UINT8 *Data;
} PRF_DATA_FRAGMENT;
typedef
IKE_PACKET *
(*IKEV2_PACKET_GENERATOR) (
IN UINT8 *SaSession,
IN VOID *Context
);
typedef
EFI_STATUS
(*IKEV2_PACKET_PARSER) (
IN UINT8 *SaSession,
IN IKE_PACKET *IkePacket
);
typedef struct {
IKEV2_PACKET_PARSER Parser;
IKEV2_PACKET_GENERATOR Generator;
} IKEV2_PACKET_HANDLER;
extern IKEV2_PACKET_HANDLER mIkev2Initial[][2];
extern IKEV2_PACKET_HANDLER mIkev2CreateChild;
extern IKEV2_PACKET_HANDLER mIkev2Info;
#endif

View File

@ -0,0 +1,401 @@
/** @file
The Implementations for Information Exchange.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Utility.h"
#include "IpSecDebug.h"
#include "IpSecConfigImpl.h"
/**
Generate Information Packet.
The information Packet may contain one Delete Payload, or Notify Payload, which
dependes on the Context's parameters.
@param[in] SaSession Pointer to IKE SA Session or Child SA Session which is
related to the information Exchange.
@param[in] Context The Data passed from the caller. If the Context is not NULL
it should contain the information for Notification Data.
@retval Pointer of IKE_PACKET generated.
**/
IKE_PACKET *
Ikev2InfoGenerator (
IN UINT8 *SaSession,
IN VOID *Context
)
{
IKEV2_SA_SESSION *IkeSaSession;
IKEV2_CHILD_SA_SESSION *ChildSaSession;
IKE_PACKET *IkePacket;
IKE_PAYLOAD *IkePayload;
IKEV2_INFO_EXCHANGE_CONTEXT *InfoContext;
InfoContext = NULL;
IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
IkePacket = IkePacketAlloc ();
ASSERT (IkePacket != NULL);
//
// Fill IkePacket Header.
//
IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_INFO;
IkePacket->Header->Version = (UINT8) (2 << 4);
if (Context != NULL) {
InfoContext = (IKEV2_INFO_EXCHANGE_CONTEXT *) Context;
}
//
// For Liveness Check
//
if (InfoContext != NULL &&
(InfoContext->InfoType == Ikev2InfoLiveCheck || InfoContext->InfoType == Ikev2InfoNotify)
) {
IkePacket->Header->MessageId = InfoContext->MessageId;
IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;
IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;
IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_NONE;
IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;
//
// TODO: add Notify Payload for Notification Information.
//
return IkePacket;
}
//
// For delete SAs
//
if (IkeSaSession->SessionCommon.IkeSessionType == IkeSessionTypeIkeSa) {
IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;
IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;
//
// If the information message is response message,the MessageId should
// be same as the request MessageId which passed through the Context.
//
if (InfoContext != NULL) {
IkePacket->Header->MessageId = InfoContext->MessageId;
} else {
IkePacket->Header->MessageId = IkeSaSession->MessageId;
Ikev2SaSessionIncreaseMessageId (IkeSaSession);
}
//
// If the state is on deleting generate a Delete Payload for it.
//
if (IkeSaSession->SessionCommon.State == IkeStateSaDeleting ) {
IkePayload = Ikev2GenerateDeletePayload (
IkeSaSession,
IKEV2_PAYLOAD_TYPE_NONE,
0,
0,
NULL
);
if (IkePayload == NULL) {
goto ERROR_EXIT;
}
//
// Fill the next payload in IkePacket's Header.
//
IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_DELETE;
IKE_PACKET_APPEND_PAYLOAD (IkePacket, IkePayload);
IkePacket->Private = IkeSaSession->SessionCommon.Private;
IkePacket->Spi = 0;
IkePacket->IsDeleteInfo = TRUE;
} else if (Context != NULL) {
//
// TODO: If contest is not NULL Generate a Notify Payload.
//
} else {
//
// The input parameter is not correct.
//
goto ERROR_EXIT;
}
} else {
//
// Delete the Child SA Information Exchagne
//
ChildSaSession = (IKEV2_CHILD_SA_SESSION *) SaSession;
IkeSaSession = ChildSaSession->IkeSaSession;
IkePacket->Header->InitiatorCookie = ChildSaSession->IkeSaSession->InitiatorCookie;
IkePacket->Header->ResponderCookie = ChildSaSession->IkeSaSession->ResponderCookie;
//
// If the information message is response message,the MessageId should
// be same as the request MessageId which passed through the Context.
//
if (InfoContext != NULL && InfoContext->MessageId != 0) {
IkePacket->Header->MessageId = InfoContext->MessageId;
} else {
IkePacket->Header->MessageId = ChildSaSession->IkeSaSession->MessageId;
Ikev2SaSessionIncreaseMessageId (IkeSaSession);
}
IkePayload = Ikev2GenerateDeletePayload (
ChildSaSession->IkeSaSession,
IKEV2_PAYLOAD_TYPE_DELETE,
4,
1,
(UINT8 *)&ChildSaSession->LocalPeerSpi
);
if (IkePayload == NULL) {
goto ERROR_EXIT;
}
//
// Fill the Next Payload in IkePacket's Header.
//
IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_DELETE;
IKE_PACKET_APPEND_PAYLOAD (IkePacket, IkePayload);
IkePacket->Private = IkeSaSession->SessionCommon.Private;
IkePacket->Spi = ChildSaSession->LocalPeerSpi;
IkePacket->IsDeleteInfo = TRUE;
if (!ChildSaSession->SessionCommon.IsInitiator) {
//
// If responder, use the MessageId fromt the initiator.
//
IkePacket->Header->MessageId = ChildSaSession->MessageId;
}
//
// Change the IsOnDeleting Flag
//
ChildSaSession->SessionCommon.IsOnDeleting = TRUE;
}
if (InfoContext == NULL) {
IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;
} else {
IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;
}
return IkePacket;
ERROR_EXIT:
if (IkePacket != NULL) {
FreePool (IkePacket);
}
return NULL;
}
/**
Parse the Info Exchange.
@param[in] SaSession Pointer to IKEV2_SA_SESSION.
@param[in] IkePacket Pointer to IkePacket related to the Information Exchange.
@retval EFI_SUCCESS The operation finised successed.
**/
EFI_STATUS
Ikev2InfoParser (
IN UINT8 *SaSession,
IN IKE_PACKET *IkePacket
)
{
IKEV2_CHILD_SA_SESSION *ChildSaSession;
IKEV2_SA_SESSION *IkeSaSession;
IKE_PAYLOAD *NotifyPayload;
IKE_PAYLOAD *DeletePayload;
IKE_PAYLOAD *IkePayload;
IKEV2_DELETE *Delete;
LIST_ENTRY *Entry;
LIST_ENTRY *ListEntry;
UINT8 Index;
UINT32 Spi;
UINT8 *SpiBuffer;
IPSEC_PRIVATE_DATA *Private;
UINT8 Value;
EFI_STATUS Status;
IKE_PACKET *RespondPacket;
IKEV2_INFO_EXCHANGE_CONTEXT Context;
IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
NotifyPayload = NULL;
DeletePayload = NULL;
Private = NULL;
RespondPacket = NULL;
Status = EFI_SUCCESS;
//
// For Liveness Check
//
if (IkePacket->Header->NextPayload == IKEV2_PAYLOAD_TYPE_NONE &&
(IkePacket->PayloadTotalSize == 0)
) {
if (IkePacket->Header->Flags == IKE_HEADER_FLAGS_INIT) {
//
// If it is Liveness check request, reply it.
//
Context.InfoType = Ikev2InfoLiveCheck;
Context.MessageId = IkePacket->Header->MessageId;
RespondPacket = Ikev2InfoGenerator ((UINT8 *)IkeSaSession, &Context);
if (RespondPacket == NULL) {
Status = EFI_INVALID_PARAMETER;
return Status;
}
Status = Ikev2SendIkePacket (
IkeSaSession->SessionCommon.UdpService,
(UINT8 *)(&IkeSaSession->SessionCommon),
RespondPacket,
0
);
} else {
//
// Todo: verify the liveness check response packet.
//
}
return Status;
}
//
// For SA Delete
//
NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {
//
// Iterate payloads to find the Delete/Notify Payload.
//
IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);
if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_DELETE) {
DeletePayload = IkePayload;
Delete = (IKEV2_DELETE *)DeletePayload->PayloadBuf;
if (Delete->SpiSize == 0) {
//
// Delete IKE SA.
//
if (IkeSaSession->SessionCommon.State == IkeStateSaDeleting) {
RemoveEntryList (&IkeSaSession->BySessionTable);
Ikev2SaSessionFree (IkeSaSession);
//
// Checking the Private status.
//
//
// when all IKE SAs were disabled by calling "IPsecConfig -disable", the IPsec
// status should be changed.
//
Private = IkeSaSession->SessionCommon.Private;
if (Private != NULL && Private->IsIPsecDisabling) {
//
// After all IKE SAs were deleted, set the IPSEC_STATUS_DISABLED value in
// IPsec status variable.
//
if (IsListEmpty (&Private->Ikev1EstablishedList) &&
(IsListEmpty (&Private->Ikev2EstablishedList))
) {
Value = IPSEC_STATUS_DISABLED;
Status = gRT->SetVariable (
IPSECCONFIG_STATUS_NAME,
&gEfiIpSecConfigProtocolGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (Value),
&Value
);
if (!EFI_ERROR (Status)) {
//
// Set the DisabledFlag in Private data.
//
Private->IpSec.DisabledFlag = TRUE;
Private->IsIPsecDisabling = FALSE;
}
}
}
} else {
IkeSaSession->SessionCommon.State = IkeStateSaDeleting;
Context.InfoType = Ikev2InfoDelete;
Context.MessageId = IkePacket->Header->MessageId;
RespondPacket = Ikev2InfoGenerator ((UINT8 *)IkeSaSession, &Context);
if (RespondPacket == NULL) {
Status = EFI_INVALID_PARAMETER;
return Status;
}
Status = Ikev2SendIkePacket (
IkeSaSession->SessionCommon.UdpService,
(UINT8 *)(&IkeSaSession->SessionCommon),
RespondPacket,
0
);
}
} else if (Delete->SpiSize == 4) {
//
// Move the Child SAs to DeleteList
//
SpiBuffer = (UINT8 *)(Delete + 1);
for (Index = 0; Index < Delete->NumSpis; Index++) {
Spi = ReadUnaligned32 ((UINT32 *)SpiBuffer);
for (ListEntry = IkeSaSession->ChildSaEstablishSessionList.ForwardLink;
ListEntry != &IkeSaSession->ChildSaEstablishSessionList;
) {
ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (ListEntry);
ListEntry = ListEntry->ForwardLink;
if (ChildSaSession->RemotePeerSpi == HTONL(Spi)) {
if (ChildSaSession->SessionCommon.State != IkeStateSaDeleting) {
//
// Insert the ChildSa Session into Delete List.
//
InsertTailList (&IkeSaSession->DeleteSaList, &ChildSaSession->ByDelete);
ChildSaSession->SessionCommon.State = IkeStateSaDeleting;
ChildSaSession->SessionCommon.IsInitiator = FALSE;
ChildSaSession->MessageId = IkePacket->Header->MessageId;
Context.InfoType = Ikev2InfoDelete;
Context.MessageId = IkePacket->Header->MessageId;
RespondPacket = Ikev2InfoGenerator ((UINT8 *)ChildSaSession, &Context);
if (RespondPacket == NULL) {
Status = EFI_INVALID_PARAMETER;
return Status;
}
Status = Ikev2SendIkePacket (
ChildSaSession->SessionCommon.UdpService,
(UINT8 *)(&ChildSaSession->SessionCommon),
RespondPacket,
0
);
} else {
//
// Delete the Child SA.
//
Ikev2ChildSaSilentDelete (IkeSaSession, Spi);
RemoveEntryList (&ChildSaSession->ByDelete);
}
}
}
SpiBuffer = SpiBuffer + sizeof (Spi);
}
}
}
}
return Status;
}
GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Info = {
Ikev2InfoParser,
Ikev2InfoGenerator
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,438 @@
/** @file
The Definitions related to IKEv2 payload.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IKE_V2_PAYLOAD_H_
#define _IKE_V2_PAYLOAD_H_
//
// Payload Type for IKEv2
//
#define IKEV2_PAYLOAD_TYPE_NONE 0
#define IKEV2_PAYLOAD_TYPE_SA 33
#define IKEV2_PAYLOAD_TYPE_KE 34
#define IKEV2_PAYLOAD_TYPE_ID_INIT 35
#define IKEV2_PAYLOAD_TYPE_ID_RSP 36
#define IKEV2_PAYLOAD_TYPE_CERT 37
#define IKEV2_PAYLOAD_TYPE_CERTREQ 38
#define IKEV2_PAYLOAD_TYPE_AUTH 39
#define IKEV2_PAYLOAD_TYPE_NONCE 40
#define IKEV2_PAYLOAD_TYPE_NOTIFY 41
#define IKEV2_PAYLOAD_TYPE_DELETE 42
#define IKEV2_PAYLOAD_TYPE_VENDOR 43
#define IKEV2_PAYLOAD_TYPE_TS_INIT 44
#define IKEV2_PAYLOAD_TYPE_TS_RSP 45
#define IKEV2_PAYLOAD_TYPE_ENCRYPT 46
#define IKEV2_PAYLOAD_TYPE_CP 47
#define IKEV2_PAYLOAD_TYPE_EAP 48
//
// IKE header Flag for IKEv2
//
#define IKE_HEADER_FLAGS_INIT 0x08
#define IKE_HEADER_FLAGS_RESPOND 0x20
#define IKE_HEADER_FLAGS_CHILD_INIT 0
//
// IKE Header Exchange Type for IKEv2
//
#define IKEV2_EXCHANGE_TYPE_INIT 34
#define IKEV2_EXCHANGE_TYPE_AUTH 35
#define IKEV2_EXCHANGE_TYPE_CREATE_CHILD 36
#define IKEV2_EXCHANGE_TYPE_INFO 37
#pragma pack(1)
typedef struct {
UINT8 NextPayload;
UINT8 Reserved;
UINT16 PayloadLength;
} IKEV2_COMMON_PAYLOAD_HEADER;
#pragma pack()
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
//
// Proposals
//
} IKEV2_SA;
#pragma pack()
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 ProposalIndex;
UINT8 ProtocolId;
UINT8 SpiSize;
UINT8 NumTransforms;
} IKEV2_PROPOSAL;
#pragma pack()
//
// IKEv2 Transform Type Values presented within Transform Payload
//
#define IKEV2_TRANSFORM_TYPE_ENCR 1 // Encryption Algorithm
#define IKEV2_TRANSFORM_TYPE_PRF 2 // Pseduo-Random Func
#define IKEV2_TRANSFORM_TYPE_INTEG 3 // Integrity Algorithm
#define IKEV2_TRANSFORM_TYPE_DH 4 // DH Group
#define IKEV2_TRANSFORM_TYPE_ESN 5 // Extended Sequence Number
//
// IKEv2 Transform ID for Encrypt Algorithm (ENCR)
//
#define IKEV2_TRANSFORM_ID_ENCR_DES_IV64 1
#define IKEV2_TRANSFORM_ID_ENCR_DES 2
#define IKEV2_TRANSFORM_ID_ENCR_3DES 3
#define IKEV2_TRANSFORM_ID_ENCR_RC5 4
#define IKEV2_TRANSFORM_ID_ENCR_IDEA 5
#define IKEV2_TRANSFORM_ID_ENCR_CAST 6
#define IKEV2_TRANSFORM_ID_ENCR_BLOWFISH 7
#define IKEV2_TRANSFORM_ID_ENCR_3IDEA 8
#define IKEV2_TRANSFORM_ID_ENCR_DES_IV32 9
#define IKEV2_TRANSFORM_ID_ENCR_NULL 11
#define IKEV2_TRANSFORM_ID_ENCR_AES_CBC 12
#define IKEV2_TRANSFORM_ID_ENCR_AES_CTR 13
//
// IKEv2 Transform ID for Pseudo-Random Function (PRF)
//
#define IKEV2_TRANSFORM_ID_PRF_HMAC_MD5 1
#define IKEV2_TRANSFORM_ID_PRF_HMAC_SHA1 2
#define IKEV2_TRANSFORM_ID_PRF_HMAC_TIGER 3
#define IKEV2_TRANSFORM_ID_PRF_AES128_XCBC 4
//
// IKEv2 Transform ID for Integrity Algorithm (INTEG)
//
#define IKEV2_TRANSFORM_ID_AUTH_NONE 0
#define IKEV2_TRANSFORM_ID_AUTH_HMAC_MD5_96 1
#define IKEV2_TRANSFORM_ID_AUTH_HMAC_SHA1_96 2
#define IKEV2_TRANSFORM_ID_AUTH_HMAC_DES_MAC 3
#define IKEV2_TRANSFORM_ID_AUTH_HMAC_KPDK_MD5 4
#define IKEV2_TRANSFORM_ID_AUTH_HMAC_AES_XCBC_96 5
//
// IKEv2 Transform ID for Diffie-Hellman Group (DH)
//
#define IKEV2_TRANSFORM_ID_DH_768MODP 1
#define IKEV2_TRANSFORM_ID_DH_1024MODP 2
#define IKEV2_TRANSFORM_ID_DH_2048MODP 14
//
// IKEv2 Attribute Type Values
//
#define IKEV2_ATTRIBUTE_TYPE_KEYLEN 14
//
// Transform Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 TransformType;
UINT8 Reserved;
UINT16 TransformId;
//
// SA Attributes
//
} IKEV2_TRANSFORM;
#pragma pack()
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT16 DhGroup;
UINT16 Reserved;
//
// Remaining part contains the key exchanged
//
} IKEV2_KEY_EXCHANGE;
#pragma pack()
//
// Identification Type Values presented within Ikev2 ID payload
//
#define IKEV2_ID_TYPE_IPV4_ADDR 1
#define IKEV2_ID_TYPE_FQDN 2
#define IKEV2_ID_TYPE_RFC822_ADDR 3
#define IKEV2_ID_TYPE_IPV6_ADDR 5
#define IKEV2_ID_TYPE_DER_ASN1_DN 9
#define IKEV2_ID_TYPE_DER_ASN1_GN 10
#define IKEV2_ID_TYPE_KEY_ID 11
//
// Identification Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 IdType;
UINT8 Reserver1;
UINT16 Reserver2;
//
// Identification Data
//
} IKEV2_ID;
#pragma pack()
//
// Encoding Type presented in IKEV2 Cert Payload
//
#define IKEV2_CERT_ENCODEING_RESERVED 0
#define IKEV2_CERT_ENCODEING_X509_CERT_WRAP 1
#define IKEV2_CERT_ENCODEING_PGP_CERT 2
#define IKEV2_CERT_ENCODEING_DNS_SIGN_KEY 3
#define IKEV2_CERT_ENCODEING_X509_CERT_SIGN 4
#define IKEV2_CERT_ENCODEING_KERBEROS_TOKEN 6
#define IKEV2_CERT_ENCODEING_REVOCATION_LIST_CERT 7
#define IKEV2_CERT_ENCODEING_AUTH_REVOCATION_LIST 8
#define IKEV2_CERT_ENCODEING_SPKI_CERT 9
#define IKEV2_CERT_ENCODEING_X509_CERT_ATTRIBUTE 10
#define IKEV2_CERT_ENCODEING_RAW_RSA_KEY 11
#define IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT 12
//
// IKEV2 Certificate Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 CertEncoding;
//
// Cert Data
//
} IKEV2_CERT;
#pragma pack()
//
// IKEV2 Certificate Request Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 CertEncoding;
//
// Cert Authority
//
} IKEV2_CERT_REQ;
#pragma pack()
//
// Authentication Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 AuthMethod;
UINT8 Reserved1;
UINT16 Reserved2;
//
// Auth Data
//
} IKEV2_AUTH;
#pragma pack()
//
// Authmethod in Authentication Payload
//
#define IKEV2_AUTH_METHOD_RSA 1; // RSA Digital Signature
#define IKEV2_AUTH_METHOD_SKMI 2; // Shared Key Message Integrity
#define IKEV2_AUTH_METHOD_DSS 3; // DSS Digital Signature
//
// IKEv2 Nonce Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
//
// Nonce Data
//
} IKEV2_NONCE;
#pragma pack()
//
// Notification Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 ProtocolId;
UINT8 SpiSize;
UINT16 MessageType;
//
// SPI and Notification Data
//
} IKEV2_NOTIFY;
#pragma pack()
//
// Notify Message Types presented within IKEv2 Notify Payload
//
#define IKEV2_NOTIFICATION_UNSUPPORT_CRITICAL_PAYLOAD 1
#define IKEV2_NOTIFICATION_INVALID_IKE_SPI 4
#define IKEV2_NOTIFICATION_INVALID_MAJOR_VERSION 5
#define IKEV2_NOTIFICATION_INVALID_SYNTAX 7
#define IKEV2_NOTIFICATION_INVALID_MESSAGE_ID 9
#define IKEV2_NOTIFICATION_INVALID_SPI 11
#define IKEV2_NOTIFICATION_NO_PROPOSAL_CHOSEN 14
#define IKEV2_NOTIFICATION_INVALID_KEY_PAYLOAD 17
#define IKEV2_NOTIFICATION_AUTHENTICATION_FAILED 24
#define IKEV2_NOTIFICATION_SINGLE_PAIR_REQUIRED 34
#define IKEV2_NOTIFICATION_NO_ADDITIONAL_SAS 35
#define IKEV2_NOTIFICATION_INTERNAL_ADDRESS_FAILURE 36
#define IKEV2_NOTIFICATION_FAILED_CP_REQUIRED 37
#define IKEV2_NOTIFICATION_TS_UNCCEPTABLE 38
#define IKEV2_NOTIFICATION_INVALID_SELECTORS 39
#define IKEV2_NOTIFICATION_COOKIE 16390
#define IKEV2_NOTIFICATION_USE_TRANSPORT_MODE 16391
#define IKEV2_NOTIFICATION_REKEY_SA 16393
//
// IKEv2 Protocol ID
//
//
// IKEv2 Delete Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 ProtocolId;
UINT8 SpiSize;
UINT16 NumSpis;
//
// SPIs
//
} IKEV2_DELETE;
#pragma pack()
//
// Traffic Selector Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 TSNumbers;
UINT8 Reserved1;
UINT16 Reserved2;
//
// Traffic Selector
//
} IKEV2_TS;
#pragma pack()
//
// Traffic Selector
//
#pragma pack(1)
typedef struct {
UINT8 TSType;
UINT8 IpProtocolId;
UINT16 SelecorLen;
UINT16 StartPort;
UINT16 EndPort;
//
// Starting Address && Ending Address
//
} TRAFFIC_SELECTOR;
#pragma pack()
//
// Ts Type in Traffic Selector
//
#define IKEV2_TS_TYPE_IPV4_ADDR_RANGE 7
#define IKEV2_TS_TYPS_IPV6_ADDR_RANGE 8
//
// Vendor Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
//
// Vendor ID
//
} IKEV2_VENDOR;
#pragma pack()
//
// Encrypted Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
//
// IV, Encrypted IKE Payloads, Padding, PAD length, Integrity CheckSum
//
} IKEV2_ENCRYPTED;
#pragma pack()
#pragma pack(1)
typedef struct {
UINT8 PadLength;
} IKEV2_PAD_LEN;
#pragma pack()
//
// Configuration Payload
//
#pragma pack(1)
typedef struct {
IKEV2_COMMON_PAYLOAD_HEADER Header;
UINT8 CfgType;
UINT8 Reserve1;
UINT16 Reserve2;
//
// Configuration Attributes
//
} IKEV2_CFG;
#pragma pack()
//
// Configuration Payload CPG type
//
#define IKEV2_CFG_TYPE_REQUEST 1
#define IKEV2_CFG_TYPE_REPLY 2
#define IKEV2_CFG_TYPE_SET 3
#define IKEV2_CFG_TYPE_ACK 4
//
// Configuration Attributes
//
#pragma pack(1)
typedef struct {
UINT16 AttritType;
UINT16 ValueLength;
} IKEV2_CFG_ATTRIBUTES;
#pragma pack()
//
// Configuration Attributes
//
#define IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS 1
#define IKEV2_CFG_ATTR_INTERNAL_IP4_NBTMASK 2
#define IKEV2_CFG_ATTR_INTERNAL_IP4_DNS 3
#define IKEV2_CFG_ATTR_INTERNAL_IP4_NBNS 4
#define IKEV2_CFG_ATTR_INTERNA_ADDRESS_BXPIRY 5
#define IKEV2_CFG_ATTR_INTERNAL_IP4_DHCP 6
#define IKEV2_CFG_ATTR_APPLICATION_VERSION 7
#define IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS 8
#define IKEV2_CFG_ATTR_INTERNAL_IP6_DNS 10
#define IKEV2_CFG_ATTR_INTERNAL_IP6_NBNS 11
#define IKEV2_CFG_ATTR_INTERNAL_IP6_DHCP 12
#define IKEV2_CFG_ATTR_INTERNAL_IP4_SUBNET 13
#define IKEV2_CFG_ATTR_SUPPORTED_ATTRIBUTES 14
#define IKEV2_CFG_ATTR_IP6_SUBNET 15
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -342,21 +342,22 @@ IpSecDuplicateProcessPolicy (
);
/**
Compare two SPD Selectors.
Find if the two SPD Selectors has subordinative.
Compare two SPD Selector by the fields of LocalAddressCount/RemoteAddressCount/
NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the
NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the
Local Addresses and remote Addresses.
@param[in] Selector1 Pointer of the first SPD Selector.
@param[in] Selector2 Pointer of the second SPD Selector.
@retval TRUE This two Selector have the same value in above fields.
@retval FALSE Not all of the above fields have the same value in these two Selectors.
@param[in] Selector1 Pointer of first SPD Selector.
@param[in] Selector2 Pointer of second SPD Selector.
@retval TRUE The first SPD Selector is subordinate Selector of second SPD Selector.
@retval FALSE The first SPD Selector is not subordinate Selector of second
SPD Selector.
**/
BOOLEAN
CompareSpdSelector (
IsSubSpdSelector (
IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,
IN EFI_IPSEC_CONFIG_SELECTOR *Selector2
);
@ -537,7 +538,7 @@ FixSpdEntry (
VOID
FixSadEntry (
IN EFI_IPSEC_SA_ID *SaId,
IN OUT EFI_IPSEC_SA_DATA *Data
IN OUT EFI_IPSEC_SA_DATA2 *Data
);
/**
@ -588,7 +589,7 @@ UnfixSpdEntry (
VOID
UnfixSadEntry (
IN OUT EFI_IPSEC_SA_ID *SaId,
IN OUT EFI_IPSEC_SA_DATA *Data
IN OUT EFI_IPSEC_SA_DATA2 *Data
);
/**
@ -949,4 +950,6 @@ EfiIpSecConfigUnregisterNotify (
IN EFI_EVENT Event
);
extern LIST_ENTRY mConfigData[IPsecConfigDataTypeMaximum];
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/** @file
Definition related to the Security operation.
Definitions related to the Cryptographic Operations in IPsec.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
@ -12,15 +12,21 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _EFI_IPSEC_CRYPTIO_H_
#define _EFI_IPSEC_CRYPTIO_H_
#include <Protocol/IpSecConfig.h>
#include <Library/DebugLib.h>
#include <Library/BaseCryptLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#define IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE 2
#include "IpSecImpl.h"
#include "IkeCommon.h"
#define IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE 4
#define IPSEC_AUTH_ALGORITHM_LIST_SIZE 3
#define IPSEC_HASH_ALGORITHM_LIST_SIZE 3
///
/// Authentication Algorithm Definition
@ -40,46 +46,49 @@
#define IKE_EALG_AESCBC 0x0C
/**
Prototype of Hash GetContextSize.
Prototype of HMAC GetContextSize.
Retrieves the size, in bytes, of the context buffer required.
@return The size, in bytes, of the context buffer required.
**/
typedef
UINTN
(EFIAPI *CPL_HASH_GETCONTEXTSIZE) (
(EFIAPI *CRYPTO_HMAC_GETCONTEXTSIZE) (
VOID
);
/**
Prototype of Hash Operation Initiating.
Prototype of HMAC Operation Initiating.
Initialization with a new context.
@param[in,out] Context Input Context.
@param[out] Context Input Context.
@param[in] Key Pointer to the key for HMAC.
@param[in] KeySize The length of the Key in bytes.
@retval TRUE Initialization Successfully.
**/
typedef
EFI_STATUS
(EFIAPI *CPL_HASH_INIT) (
IN OUT VOID *Context
BOOLEAN
(EFIAPI *CRYPTO_HMAC_INIT) (
OUT VOID *Context,
IN CONST UINT8 *Key,
IN UINTN KeySize
);
/**
Prototype of HASH update.
Hash update operation. Continue an Hash message digest operation, processing
another message block, and updating the Hash context.
Prototype of HMAC update.
HMAC update operation. Continue an HMAC message digest operation, processing
another message block, and updating the HMAC context.
If Context is NULL, then ASSERT().
If Data is NULL, then ASSERT().
@param[in,out] Context The Specified Context.
@param[in,out] Data The Input Data to hash.
@param[in,out] Data The Input Data to be digested.
@param[in] DataLength The length, in bytes, of Data.
@retval TRUE Update data successfully.
@ -88,34 +97,34 @@ EFI_STATUS
**/
typedef
BOOLEAN
(EFIAPI *CPL_HASH_UPDATE) (
(EFIAPI *CRYPTO_HMAC_UPDATE) (
IN OUT VOID *Context,
IN CONST VOID *Data,
IN UINTN DataLength
);
/**
Prototype of Hash finallization.
Terminate a Hash message digest operation and output the message digest.
Prototype of HMAC finallization.
Terminate a HMAC message digest operation and output the message digest.
If Context is NULL, then ASSERT().
If HashValue is NULL, then ASSERT().
@param[in,out] Context The specified Context.
@param[out] HashValue Pointer to a 16-byte message digest output buffer.
@param[out] HmacValue Pointer to a 16-byte message digest output buffer.
@retval TRUE Finalized successfully.
**/
typedef
BOOLEAN
(EFIAPI *CPL_HASH_FINAL) (
(EFIAPI *CRYPTO_HMAC_FINAL) (
IN OUT VOID *Context,
OUT UINT8 *HashValue
OUT UINT8 *HmacValue
);
/**
Prototype of Cipher GetContextSize.
Prototype of Block Cipher GetContextSize.
Retrieves the size, in bytes, of the context buffer required.
@ -124,12 +133,12 @@ BOOLEAN
**/
typedef
UINTN
(EFIAPI *CPL_CIPHER_GETCONTEXTSIZE) (
(EFIAPI *CRYPTO_CIPHER_GETCONTEXTSIZE) (
VOID
);
/**
Prototype of Cipher initiation.
Prototype of Block Cipher initiation.
Intializes the user-supplied key as the specifed context (key materials) for both
encryption and decryption operations.
@ -137,21 +146,20 @@ UINTN
If Key is NULL, then generate random key for usage.
@param[in,out] Context The specified Context.
@param[in] Key User-supplied TDES key (64/128/192 bits).
@param[in] Key User-supplied cipher key.
@param[in] KeyBits Key length in bits.
@retval TRUE TDES Initialization was successful.
@retval TRUE Block Cipher Initialization was successful.
**/
typedef
BOOLEAN
(EFIAPI *CPL_CIPHER_INIT) (
(EFIAPI *CRYPTO_CIPHER_INIT) (
IN OUT VOID *Context,
IN CONST UINT8 *Key,
IN CONST UINTN KeyBits
IN UINTN KeyBits
);
/**
Prototype of Cipher encryption.
Encrypts plaintext message with the specified cipher.
@ -163,22 +171,23 @@ BOOLEAN
@param[in] Context The specified Context.
@param[in] InData The input plaintext data to be encrypted.
@param[in] InputSize The size of input data.
@param[in] Ivec Pointer to Initial Vector data for encryption.
@param[out] OutData The resultant encrypted ciphertext.
@param[in] DataLength Length of input data in bytes.
@retval TRUE Encryption successful.
**/
typedef
BOOLEAN
(EFIAPI *CPL_CIPHER_ENCRYPT) (
(EFIAPI *CRYPTO_CIPHER_ENCRYPT) (
IN VOID *Context,
IN CONST UINT8 *InData,
OUT UINT8 *OutData,
IN CONST UINTN DataLength
IN UINTN InputSize,
IN CONST UINT8 *Ivec,
OUT UINT8 *OutData
);
/**
Prototype of Cipher decryption.
Decrypts cipher message with specified cipher.
@ -189,61 +198,154 @@ BOOLEAN
@param[in] Context The specified Context.
@param[in] InData The input ciphertext data to be decrypted.
@param[in] InputSize The InData size.
@param[in] Ivec Pointer to the Initial Vector data for decryption.
@param[out] OutData The resultant decrypted plaintext.
@param[in] DataLength Length of input data in bytes.
@retval TRUE Decryption successful.
**/
typedef
BOOLEAN
(EFIAPI *CPL_CIPHER_DECRYPT) (
IN CONST VOID *Context,
(EFIAPI *CRYPTO_CIPHER_DECRYPT) (
IN VOID *Context,
IN CONST UINT8 *InData,
OUT UINT8 *OutData,
IN CONST UINTN DataLength
IN UINTN InputSize,
IN CONST UINT8 *Ivec,
OUT UINT8 *OutData
);
/**
Prototype of Hash ContextSize.
Retrieves the size, in bytes, of the context buffer required for specified hash operations.
@return The size, in bytes, of the context buffer required for certain hash operations.
**/
typedef
UINTN
(EFIAPI *CRYPTO_HASH_GETCONTEXTSIZE) (
VOID
);
/**
Prototype of Hash Initiate.
Initializes user-supplied memory pointed by Context as specified hash context for
subsequent use.
If Context is NULL, then ASSERT().
@param[out] Context Pointer to specified context being initialized.
@retval TRUE context initialization succeeded.
@retval FALSE context initialization failed.
**/
typedef
BOOLEAN
(EFIAPI *CRYPTO_HASH_INIT) (
OUT VOID *Context
);
/**
Prototype of Hash Update
Digests the input data and updates hash context.
This function performs digest on a data buffer of the specified size.
It can be called multiple times to compute the digest of long or discontinuous data streams.
Context should be already correctly intialized by HashInit(), and should not be finalized
by HashFinal(). Behavior with invalid context is undefined.
If Context is NULL, then ASSERT().
@param[in, out] Context Pointer to the specified context.
@param[in] Data Pointer to the buffer containing the data to be hashed.
@param[in] DataSize Size of Data buffer in bytes.
@retval TRUE data digest succeeded.
@retval FALSE data digest failed.
**/
typedef
BOOLEAN
(EFIAPI *CRYPTO_HASH_UPDATE) (
IN OUT VOID *Context,
IN CONST VOID *Data,
IN UINTN DataSize
);
/**
Prototype of Hash Finalization.
Completes computation of the digest value.
This function completes hash computation and retrieves the digest value into
the specified memory. After this function has been called, the context cannot
be used again.
context should be already correctly intialized by HashInit(), and should not be
finalized by HashFinal(). Behavior with invalid context is undefined.
If Context is NULL, then ASSERT().
If HashValue is NULL, then ASSERT().
@param[in, out] Context Pointer to the specified context.
@param[out] HashValue Pointer to a buffer that receives the digest
value.
@retval TRUE digest computation succeeded.
@retval FALSE digest computation failed.
**/
typedef
BOOLEAN
(EFIAPI *CRYPTO_HASH_FINAL) (
IN OUT VOID *Context,
OUT UINT8 *HashValue
);
//
// The struct used to store the informatino and operation of Cipher algorithm.
// The struct used to store the information and operation of Block Cipher algorithm.
//
typedef struct _ENCRYPT_ALGORITHM {
//
// The ID of the Algorithm
//
UINT8 AlgorithmId;
//
// The Key length of the Algorithm
//
UINTN KeyLength;
//
// Iv Size of the Algorithm
//
UINTN IvLength;
//
// The Block Size of the Algorithm
//
UINTN BlockSize;
//
// The Function pointer of GetContextSize.
//
CPL_CIPHER_GETCONTEXTSIZE CipherGetContextSize;
//
// The Function pointer of Cipher intitiaion.
//
CPL_CIPHER_INIT CipherInitiate;
//
// The Function pointer of Cipher Encryption.
//
CPL_CIPHER_ENCRYPT CipherEncrypt;
//
// The Function pointer of Cipher Decrption.
//
CPL_CIPHER_DECRYPT CipherDecrypt;
//
// The ID of the Algorithm
//
UINT8 AlgorithmId;
//
// The Key length of the Algorithm
//
UINTN KeyLength;
//
// Iv Size of the Algorithm
//
UINTN IvLength;
//
// The Block Size of the Algorithm
//
UINTN BlockSize;
//
// The Function pointer of GetContextSize.
//
CRYPTO_CIPHER_GETCONTEXTSIZE CipherGetContextSize;
//
// The Function pointer of Cipher initiation.
//
CRYPTO_CIPHER_INIT CipherInitiate;
//
// The Function pointer of Cipher Encryption.
//
CRYPTO_CIPHER_ENCRYPT CipherEncrypt;
//
// The Function pointer of Cipher Decrption.
//
CRYPTO_CIPHER_DECRYPT CipherDecrypt;
} ENCRYPT_ALGORITHM;
//
// The struct used to store the informatino and operation of Autahentication algorithm.
// The struct used to store the information and operation of Autahentication algorithm.
//
typedef struct _AUTH_ALGORITHM {
//
@ -252,8 +354,8 @@ typedef struct _AUTH_ALGORITHM {
UINT8 AlgorithmId;
//
// The Key length of the Algorithm
//
UINTN KeyLength;
//
UINTN DigestLength;
//
// The ICV length of the Algorithm
//
@ -265,25 +367,63 @@ typedef struct _AUTH_ALGORITHM {
//
// The function pointer of GetContextSize.
//
CPL_HASH_GETCONTEXTSIZE HashGetContextSize;
CRYPTO_HMAC_GETCONTEXTSIZE HmacGetContextSize;
//
// The function pointer of Initiatoion
// The function pointer of Initiation
//
CPL_HASH_INIT HashInitiate;
CRYPTO_HMAC_INIT HmacInitiate;
//
// The function pointer of Hash Update.
// The function pointer of HMAC Update.
//
CPL_HASH_UPDATE HashUpdate;
CRYPTO_HMAC_UPDATE HmacUpdate;
//
// The fucntion pointer of HMAC Final
//
CRYPTO_HMAC_FINAL HmacFinal;
} AUTH_ALGORITHM;
//
// The struct used to store the informatino and operation of Hash algorithm.
//
typedef struct _HASH_ALGORITHM {
//
// ID of the Algorithm
//
UINT8 AlgorithmId;
//
// The Key length of the Algorithm
//
UINTN DigestLength;
//
// The ICV length of the Algorithm
//
UINTN IcvLength;
//
// The block size of the Algorithm
//
UINTN BlockSize;
//
// The function pointer of GetContextSize
//
CRYPTO_HASH_GETCONTEXTSIZE HashGetContextSize;
//
// The function pointer of Initiation
//
CRYPTO_HASH_INIT HashInitiate;
//
// The function pointer of Hash Update
//
CRYPTO_HASH_UPDATE HashUpdate;
//
// The fucntion pointer of Hash Final
//
CPL_HASH_FINAL HashFinal;
} AUTH_ALGORITHM;
CRYPTO_HASH_FINAL HashFinal;
} HASH_ALGORITHM;
/**
Get the IV size of encrypt alogrithm. IV size is different from different algorithm.
Get the IV size of specified encryption alogrithm.
@param[in] AlgorithmId The encrypt algorithm ID.
@param[in] AlgorithmId The encryption algorithm ID.
@return The value of IV size.
@ -294,9 +434,9 @@ IpSecGetEncryptIvLength (
);
/**
Get the block size of encrypt alogrithm. Block size is different from different algorithm.
Get the block size of specified encryption alogrithm.
@param[in] AlgorithmId The encrypt algorithm ID.
@param[in] AlgorithmId The encryption algorithm ID.
@return The value of block size.
@ -307,16 +447,42 @@ IpSecGetEncryptBlockSize (
);
/**
Get the ICV size of Authenticaion alogrithm. ICV size is different from different algorithm.
Get the required key length of the specified encryption alogrithm.
@param[in] AuthAlgorithmId The Authentication algorithm ID.
@param[in] AlgorithmId The encryption algorithm ID.
@return The value of key length.
**/
UINTN
IpSecGetEncryptKeyLength (
IN UINT8 AlgorithmId
);
/**
Get the ICV size of the specified Authenticaion alogrithm.
@param[in] AlgorithmId The Authentication algorithm ID.
@return The value of ICV size.
**/
UINTN
IpSecGetIcvLength (
IN UINT8 AuthAlgorithmId
IN UINT8 AlgorithmId
);
/**
Get the HMAC digest length by the specified Algorithm ID.
@param[in] AlgorithmId The specified Alogrithm ID.
@return The digest length of the specified Authentication Algorithm ID.
**/
UINTN
IpSecGetHmacDigestLength (
IN UINT8 AlgorithmId
);
/**
@ -324,7 +490,7 @@ IpSecGetIcvLength (
IV and return EFI_SUCCESS.
@param[in] IvBuffer The pointer of the IV buffer.
@param[in] IvSize The IV size.
@param[in] IvSize The IV size in bytes.
@retval EFI_SUCCESS Create random data for IV.
@ -335,5 +501,327 @@ IpSecGenerateIv (
IN UINTN IvSize
);
/**
Encrypt the buffer.
This function calls relevant encryption interface from CryptoLib according to
the input alogrithm ID. The InData should be multiple of block size. This function
doesn't perform the padding. If it has the Ivec data, the length of it should be
same with the block size. The block size is different from the different algorithm.
@param[in] AlgorithmId The Alogrithem identification defined in RFC.
@param[in] Key Pointer to the buffer containing encrypting key.
@param[in} KeyBits The length of the key in bits.
@param[in] Ivec Point to the buffer containning the Initializeion
Vector (IV) data.
@param[in] InData Point to the buffer containing the data to be
encrypted.
@param[in] InDataLength The length of InData in Bytes.
@param[out] OutData Point to the buffer that receives the encryption
output.
@retval EFI_UNSUPPORTED The input Algorithm is not supported.
@retval EFI_OUT_OF_RESOURCE The required resource can't be allocated.
@retval EFI_SUCCESS The operation completed successfully.
**/
EFI_STATUS
IpSecCryptoIoEncrypt (
IN CONST UINT8 AlgorithmId,
IN CONST UINT8 *Key,
IN CONST UINTN KeyBits,
IN CONST UINT8 *Ivec, OPTIONAL
IN UINT8 *InData,
IN UINTN InDataLength,
OUT UINT8 *OutData
);
/**
Decrypts the buffer.
This function calls relevant Decryption interface from CryptoLib according to
the input alogrithm ID. The InData should be multiple of block size. This function
doesn't perform the padding. If it has the Ivec data, the length of it should be
same with the block size. The block size is different from the different algorithm.
@param[in] AlgorithmId The Alogrithem identification defined in RFC.
@param[in] Key Pointer to the buffer containing encrypting key.
@param[in} KeyBits The length of the key in bits.
@param[in] Ivec Point to the buffer containning the Initializeion
Vector (IV) data.
@param[in] InData Point to the buffer containing the data to be
Decrypted.
@param[in] InDataLength The length of InData in Bytes.
@param[out] OutData Pointer to the buffer that receives the decryption
output.
@retval EFI_UNSUPPORTED The input Algorithm is not supported.
@retval EFI_OUT_OF_RESOURCE The required resource can't be allocated.
@retval EFI_SUCCESS The operation completed successfully.
**/
EFI_STATUS
IpSecCryptoIoDecrypt (
IN CONST UINT8 AlgorithmId,
IN CONST UINT8 *Key,
IN CONST UINTN KeyBits,
IN CONST UINT8 *Ivec, OPTIONAL
IN UINT8 *InData,
IN UINTN InDataLength,
OUT UINT8 *OutData
);
/**
Digests the Payload with key and store the result into the OutData.
This function calls relevant Hmac interface from CryptoLib according to
the input alogrithm ID. It computes all datas from InDataFragment and output
the result into the OutData buffer. If the OutDataSize is larger than the related
HMAC alogrithm output size, return EFI_INVALID_PARAMETER.
@param[in] AlgorithmId The authentication Identification.
@param[in] Key Pointer of the authentication key.
@param[in] KeyLength The length of the Key in bytes.
@param[in] InDataFragment The list contains all data to be authenticated.
@param[in] FragmentCount The size of the InDataFragment.
@param[out] OutData For in, the buffer to receive the output data.
For out, the buffer contains the authenticated data.
@param[in] OutDataSize The size of the buffer of OutData.
@retval EFI_UNSUPPORTED If the AuthAlg is not in the support list.
@retval EFI_INVALID_PARAMETER The OutData buffer size is larger than algorithm digest size.
@retval EFI_SUCCESS Authenticate the payload successfully.
@retval otherwise Authentication of the payload fails.
**/
EFI_STATUS
IpSecCryptoIoHmac (
IN CONST UINT8 AlgorithmId,
IN CONST UINT8 *Key,
IN UINTN KeyLength,
IN HASH_DATA_FRAGMENT *InDataFragment,
IN UINTN FragmentCount,
OUT UINT8 *OutData,
IN UINTN OutDataSize
);
/**
Digests the Payload and store the result into the OutData.
This function calls relevant Hash interface from CryptoLib according to
the input alogrithm ID. It computes all datas from InDataFragment and output
the result into the OutData buffer. If the OutDataSize is larger than the related
Hash alogrithm output size, return EFI_INVALID_PARAMETER.
@param[in] AlgorithmId The authentication Identification.
@param[in] InDataFragment A list contains all data to be authenticated.
@param[in] FragmentCount The size of the InDataFragment.
@param[out] OutData For in, the buffer to receive the output data.
For out, the buffer contains the authenticated data.
@param[in] OutDataSize The size of the buffer of OutData.
@retval EFI_UNSUPPORTED If the AuthAlg is not in the support list.
@retval EFI_SUCCESS Authenticated the payload successfully.
@retval EFI_INVALID_PARAMETER If the OutDataSize is larger than the related Hash
algorithm could handle.
@retval otherwise Authentication of the payload failed.
**/
EFI_STATUS
IpSecCryptoIoHash (
IN CONST UINT8 AlgorithmId,
IN HASH_DATA_FRAGMENT *InDataFragment,
IN UINTN FragmentCount,
OUT UINT8 *OutData,
IN UINTN OutDataSize
);
/**
Generates the Diffie-Hellman public key.
This function first initiate a DHContext, then call the DhSetParameter() to set
the prime and primelenght, at end call the DhGenerateKey() to generates random
secret exponent, and computes the public key. The output returned via parameter
PublicKey and PublicKeySize. DH context is updated accordingly. If the PublicKey
buffer is too small to hold the public key, EFI_INVALID_PARAMETER is returned
and PublicKeySize is set to the required buffer size to obtain the public key.
@param[in, out] DhContext Pointer to the DH context.
@param[in] Generator Vlaue of generator.
@param[in] PrimeLength Length in bits of prime to be generated.
@param[in] Prime Pointer to the buffer to receive the generated
prime number.
@param[out] PublicKey Pointer to the buffer to receive generated public key.
@param[in, out] PublicKeySize For in, the size of PublicKey buffer in bytes.
For out, the size of data returned in PublicKey
buffer in bytes.
@retval EFI_SUCCESS The operation perfoms successfully.
@retval Otherwise The operation is failed.
**/
EFI_STATUS
IpSecCryptoIoDhGetPublicKey (
IN OUT UINT8 **DhContext,
IN UINTN Generator,
IN UINTN PrimeLength,
IN CONST UINT8 *Prime,
OUT UINT8 *PublicKey,
IN OUT UINTN *PublicKeySize
);
/**
Generates exchanged common key.
Given peer's public key, this function computes the exchanged common key, based
on its own context including value of prime modulus and random secret exponent.
@param[in, out] DhContext Pointer to the DH context.
@param[in] PeerPublicKey Pointer to the peer's Public Key.
@param[in] PeerPublicKeySize Size of peer's public key in bytes.
@param[out] Key Pointer to the buffer to receive generated key.
@param[in, out] KeySize For in, the size of Key buffer in bytes.
For out, the size of data returned in Key
buffer in bytes.
@retval EFI_SUCCESS The operation perfoms successfully.
@retval Otherwise The operation is failed.
**/
EFI_STATUS
IpSecCryptoIoDhComputeKey (
IN OUT UINT8 *DhContext,
IN CONST UINT8 *PeerPublicKey,
IN UINTN PeerPublicKeySize,
OUT UINT8 *Key,
IN OUT UINTN *KeySize
);
/**
Releases the DH context. If DhContext is NULL, return EFI_INVALID_PARAMETER.
@param[in, out] DhContext Pointer to the DH context to be freed.
@retval EFI_SUCCESS The operation perfoms successfully.
@retval EFI_INVALID_PARAMETER The DhContext is NULL.
**/
EFI_STATUS
IpSecCryptoIoFreeDh (
IN OUT UINT8 **DhContext
);
/**
Generates random numbers of specified size.
If the Random Generator wasn't initiated, initiate it first, then call RandomBytes.
@param[out] OutBuffer Pointer to buffer to receive random value.
@param[in] Bytes Size of randome bytes to generate.
@retval EFI_SUCCESS The operation perfoms successfully.
@retval Otherwise The operation is failed.
**/
EFI_STATUS
IpSecCryptoIoGenerateRandomBytes (
OUT UINT8* OutBuffer,
IN UINTN Bytes
);
/**
Authenticate data with the certificate.
@param[in] InData Pointer to the Data to be signed.
@param[in] InDataSize InData size in bytes.
@param[in] PrivateKey Pointer to the private key.
@param[in] PrivateKeySize The size of Private Key in bytes.
@param[in] KeyPassWord Pointer to the password for retrieving private key.
@param[in] KeyPwdSize The size of Key Password in bytes.
@param[out] OutData The pointer to the signed data.
@param[in, out] OutDataSize Pointer to contain the size of out data.
**/
VOID
IpSecCryptoIoAuthDataWithCertificate (
IN UINT8 *InData,
IN UINTN InDataSize,
IN UINT8 *PrivateKey,
IN UINTN PrivateKeySize,
IN UINT8 *KeyPassWord,
IN UINTN KeyPwdSize,
OUT UINT8 **OutData,
IN OUT UINTN *OutDataSize
);
/**
Verify the singed data with the public key which is contained in a certificate.
@param[in] InCert Pointer to the Certificate which contains the
public key.
@param[in] InCertLen The size of Certificate in bytes.
@param[in] InCa Pointer to the CA certificate
@param[in] CaLen The size of CA certificate in bytes.
@param[in] InData Pointer to octect message hash to be checked.
@param[in] InDataSize Size of the message hash in bytes.
@param[in] Singnature The pointer to the RSA PKCS1-V1_5 signature to be verifed.
@param[in] SigSize Size of signature in bytes.
@retval TRUE Valid signature encoded in PKCS1-v1_5.
@retval FALSE Invalid signature or invalid RSA context.
**/
BOOLEAN
IpSecCryptoIoVerifySignDataByCertificate (
IN UINT8 *InCert,
IN UINTN CertLen,
IN UINT8 *InCa,
IN UINTN CaLen,
IN UINT8 *InData,
IN UINTN InDataSize,
IN UINT8 *Singnature,
IN UINTN SigSize
);
/**
Retrieves the RSA Public Key from one X509 certificate (DER format only).
@param[in] InCert Pointer to the certificate.
@param[in] CertLen The size of the certificate in bytes.
@param[out] PublicKey Pointer to the retrieved public key.
@param[out] PublicKeyLen Size of Public Key in bytes.
@retval EFI_SUCCESS Successfully get the public Key.
@retval EFI_INVALID_PARAMETER The CA certificate is malformed.
**/
EFI_STATUS
IpSecCryptoIoGetPublicKeyFromCert (
IN UINT8 *InCert,
IN UINTN CertLen,
OUT UINT8 **PublicKey,
OUT UINTN *PublicKeyLen
);
/**
Retrieves the subject name from one X509 certificate (DER format only).
@param[in] InCert Pointer to the X509 certificate.
@param[in] CertSize The size of the X509 certificate in bytes.
@param[out] CertSubject Pointer to the retrieved certificate subject.
@param[out] SubjectSize The size of Certificate Subject in bytes.
@retval EFI_SUCCESS Retrieved the certificate subject successfully.
@retval EFI_INVALID_PARAMETER The certificate is malformed.
**/
EFI_STATUS
IpSecCryptoIoGetSubjectFromCert (
IN UINT8 *InCert,
IN UINTN CertSize,
OUT UINT8 **CertSubject,
OUT UINTN *SubjectSize
);
#endif

View File

@ -1,5 +1,5 @@
/** @file
Interface of IPsec printing debug information.
The Interfaces of IPsec debug information printing.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
@ -19,7 +19,7 @@
//
// The print title for IKEv1 variety phase.
//
CHAR8 *mStateStr[] = {
CHAR8 *mIkev1StateStr[] = {
"IKEv1_MAIN_1",
"IKEv1_MAIN_2",
"IKEv1_MAIN_3",
@ -28,6 +28,20 @@ CHAR8 *mStateStr[] = {
"IKEv1_QUICK_2",
"IKEv1_QUICK_ESTABLISHED"
};
//
// The print title for IKEv2 variety phase.
//
CHAR8 *mIkev2StateStr[] = {
"IKEv2_STATE_INIT",
"IKEv2_STATE_AUTH",
"IKEv2_STATE_SA_ESTABLISH",
"IKEv2_STATE_CREATE_CHILD",
"IKEv2_STATE_SA_REKEYING",
"IKEv2_STATE_CHILD_SA_ESTABLISHED",
"IKEv2_STATE_SA_DELETING"
};
//
// The print title for IKEv1 variety Exchagne.
//
@ -35,13 +49,17 @@ CHAR8 *mExchangeStr[] = {
"IKEv1 Main Exchange",
"IKEv1 Info Exchange",
"IKEv1 Quick Exchange",
"IKEv1 Unknown Exchange"
"IKEv2 Initial Exchange",
"IKEv2 Auth Exchange",
"IKEv2 Create Child Exchange",
"IKEv2 Info Exchange",
"IKE Unknow Exchange"
};
//
// The print title for IKEv1 variety Payload.
//
CHAR8 *mPayloadStr[] = {
CHAR8 *mIkev1PayloadStr[] = {
"IKEv1 None Payload",
"IKEv1 SA Payload",
"IKEv1 Proposal Payload",
@ -58,6 +76,28 @@ CHAR8 *mPayloadStr[] = {
"IKEv1 Vendor Payload"
};
//
// The print title for IKEv2 variety Payload.
//
CHAR8* mIkev2PayloadStr[] = {
"IKEv2 SA Payload",
"IKEv2 Key Payload",
"IKEv2 Identity Initial Payload",
"IKEv2 Identity Respond Payload",
"IKEv2 Certificate Payload",
"IKEv2 Certificate Request Payload",
"IKEv2 Auth Payload",
"IKEv2 Nonce Payload",
"IKEv2 Notify Payload",
"IKEv2 Delet Payload",
"IKEv2 Vendor Payload",
"IKEv2 Traffic Selector Initiator Payload",
"IKEv2 Traffic Selector Respond Payload",
"IKEv2 Encrypt Payload",
"IKEv2 Configuration Payload",
"IKEv2 Extensible Authentication Payload"
};
/**
Print the IP address.
@ -112,26 +152,148 @@ IpSecDumpAddress (
}
/**
Print IKEv1 Current states.
Print IKE Current states.
@param[in] Previous The Previous state of IKEv1.
@param[in] Current The current state of IKEv1.
@param[in] Previous The Previous state of IKE.
@param[in] Current The current state of IKE.
@param[in] IkeVersion The version of IKE.
**/
VOID
IpSecDumpState (
IkeDumpState (
IN UINT32 Previous,
IN UINT32 Current
IN UINT32 Current,
IN UINT8 IkeVersion
)
{
if (Previous == Current) {
DEBUG ((DEBUG_INFO, "\n****Current state is %a\n", mStateStr[Previous]));
if (IkeVersion == 1) {
DEBUG ((DEBUG_INFO, "\n****Current state is %a\n", mIkev1StateStr[Previous]));
} else if (IkeVersion == 2) {
DEBUG ((DEBUG_INFO, "\n****Current state is %a\n", mIkev2StateStr[Previous]));
}
} else {
DEBUG ((DEBUG_INFO, "\n****Change state from %a to %a\n", mStateStr[Previous], mStateStr[Current]));
if (IkeVersion == 1) {
DEBUG ((DEBUG_INFO, "\n****Change state from %a to %a\n", mIkev1StateStr[Previous], mIkev1StateStr[Current]));
} else {
DEBUG ((DEBUG_INFO, "\n****Change state from %a to %a\n", mIkev2StateStr[Previous], mIkev2StateStr[Current]));
}
}
}
/**
Print the IKE Packet.
@param[in] Packet Point to IKE packet to be printed.
@param[in] Direction Point to the IKE packet is inbound or outbound.
@param[in] IpVersion Specified IP Version.
**/
VOID
IpSecDumpPacket (
IN IKE_PACKET *Packet,
IN EFI_IPSEC_TRAFFIC_DIR Direction,
IN UINT8 IpVersion
)
{
CHAR8 *TypeStr;
UINTN PacketSize;
UINT64 InitCookie;
UINT64 RespCookie;
ASSERT (Packet != NULL);
PacketSize = Packet->PayloadTotalSize + sizeof (IKE_HEADER);
InitCookie = (Direction == EfiIPsecOutBound) ? HTONLL (Packet->Header->InitiatorCookie) : Packet->Header->InitiatorCookie;
RespCookie = (Direction == EfiIPsecOutBound) ? HTONLL (Packet->Header->ResponderCookie) : Packet->Header->ResponderCookie;
switch (Packet->Header->ExchangeType) {
case IKE_XCG_TYPE_IDENTITY_PROTECT:
TypeStr = mExchangeStr[0];
break;
case IKE_XCG_TYPE_INFO:
TypeStr = mExchangeStr[1];
break;
case IKE_XCG_TYPE_QM:
TypeStr = mExchangeStr[2];
break;
case IKE_XCG_TYPE_SA_INIT:
TypeStr = mExchangeStr[3];
break;
case IKE_XCG_TYPE_AUTH:
TypeStr = mExchangeStr[4];
break;
case IKE_XCG_TYPE_CREATE_CHILD_SA:
TypeStr = mExchangeStr[5];
break;
case IKE_XCG_TYPE_INFO2:
TypeStr = mExchangeStr[6];
break;
default:
TypeStr = mExchangeStr[7];
break;
}
if (Direction == EfiIPsecOutBound) {
DEBUG ((DEBUG_INFO, "\n>>>Sending %d bytes %a to ", PacketSize, TypeStr));
} else {
DEBUG ((DEBUG_INFO, "\n>>>Receiving %d bytes %a from ", PacketSize, TypeStr));
}
IpSecDumpAddress (DEBUG_INFO, &Packet->RemotePeerIp, IpVersion);
DEBUG ((DEBUG_INFO, " InitiatorCookie:0x%lx ResponderCookie:0x%lx\n", InitCookie, RespCookie));
DEBUG (
(DEBUG_INFO,
" Version: 0x%x Flags:0x%x ExchangeType:0x%x\n",
Packet->Header->Version,
Packet->Header->Flags,
Packet->Header->ExchangeType)
);
DEBUG (
(DEBUG_INFO,
" MessageId:0x%x NextPayload:0x%x\n",
Packet->Header->MessageId,
Packet->Header->NextPayload)
);
}
/**
Print the IKE Paylolad.
@param[in] IkePayload Point to payload to be printed.
@param[in] IkeVersion The specified version of IKE.
**/
VOID
IpSecDumpPayload (
IN IKE_PAYLOAD *IkePayload,
IN UINT8 IkeVersion
)
{
if (IkeVersion == 1) {
DEBUG ((DEBUG_INFO, "+%a\n", mIkev1PayloadStr[IkePayload->PayloadType]));
} else {
//
// For IKEV2 the first Payload type is started from 33.
//
DEBUG ((DEBUG_INFO, "+%a\n", mIkev2PayloadStr[IkePayload->PayloadType - 33]));
}
IpSecDumpBuf ("Payload data", IkePayload->PayloadBuf, IkePayload->PayloadSize);
}
/**
Print the buffer in form of Hex.

View File

@ -1,5 +1,5 @@
/** @file
The definition of functions and MACROs used for IPsec debug information print.
The definition of functions and MACROs used for IPsec debug information printting.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
@ -12,16 +12,18 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _EFI_IPSEC_DEBUG_H_
#define _EFI_IPSEC_DEBUG_H_
#include <Library/DebugLib.h>
#include "IkeCommon.h"
#include "IkePacket.h"
#define IPSEC_DUMP_ADDRESS(Level, Ip, Version) IpSecDumpAddress (Level, Ip, Version)
#define IPSEC_DUMP_STATE(Previous, Current) IpSecDumpState (Previous, Current)
#define IKEV1_DUMP_STATE(Previous, Current) IkeDumpState (Previous, Current, 1)
#define IKEV2_DUMP_STATE(Previous, Current) IkeDumpState (Previous, Current, 2)
#define IPSEC_DUMP_PACKET(Packet, Direction, IpVersion) IpSecDumpPacket (Packet, Direction, IpVersion)
#define IPSEC_DUMP_PAYLOAD(IkePayload) IpSecDumpPayload (IkePayload)
#define IPSEC_DUMP_PAYLOAD(IkePayload) IpSecDumpPayload (IkePayload, 1)
#define IKEV2_DUMP_PAYLOAD(IkePayload) IpSecDumpPayload (IkePayload, 2)
#define IPSEC_DUMP_BUF(Title, Data, DataSize) IpSecDumpBuf (Title, Data, DataSize)
#define IPSEC_DEBUG_BYTE_PER_LINE 8
@ -43,52 +45,53 @@ IpSecDumpAddress (
);
/**
Print IKEv1 Current states.
Print IKE Current states.
@param[in] Previous The Previous state of IKEv1.
@param[in] Current The current state of IKEv1.
@param[in] Previous The Previous state of IKE.
@param[in] Current The current state of IKE.
@param[in] IkeVersion The version of IKE.
**/
VOID
IpSecDumpState (
IkeDumpState (
IN UINT32 Previous,
IN UINT32 Current
IN UINT32 Current,
IN UINT8 IkeVersion
);
/**
Print the Ike Packet.
Print the IKE Packet.
@param[in] Packet Point to IKE packet to be printed.
@param[in] Direction Point to the IKE packet is inbound or outbound.
@param[in] IpVersion Specified IP Version.
**/
/*
VOID
IpSecDumpPacket (
IN IKE_PACKET *Packet,
IN EFI_IPSEC_TRAFFIC_DIR Direction,
IN UINT8 IpVersion
);
*/
/**
Print the IKE Paylolad.
@param[in] IkePayload Points to the payload to be printed.
@param[in] IkePayload Point to payload to be printed.
@param[in] IkeVersion The specified version of IKE.
**/
/*
VOID
IpSecDumpPayload (
IN IKE_PAYLOAD *IkePayload
IN IKE_PAYLOAD *IkePayload,
IN UINT8 IkeVersion
);
*/
/**
Print the buffer in form of Hex.
@param[in] Title The strings to be printed before the data of the buffer.
@param[in] Data Points to the buffer to be printed.
@param[in] Data Point to buffer to be printed.
@param[in] DataSize The size of the buffer to be printed.
**/

View File

@ -13,8 +13,10 @@
**/
#include <Library/UdpIoLib.h>
#include <Library/BaseCryptLib.h>
#include "IpSecConfigImpl.h"
#include "IkeService.h"
#include "IpSecDebug.h"
/**
@ -38,9 +40,34 @@ IpSecDriverBindingSupported (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
EFI_STATUS Udp4Status;
EFI_STATUS Udp6Status;
Udp4Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUdp4ServiceBindingProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
Udp6Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUdp6ServiceBindingProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
//
//TODO: Add Udp4Protocol and Udp6Protocol testing.
// The controller with either Udp4Sb or Udp6Sb is supported.
//
if (!EFI_ERROR (Udp4Status) || !EFI_ERROR (Udp6Status)) {
return EFI_SUCCESS;
}
return EFI_UNSUPPORTED;
}
@ -54,7 +81,7 @@ IpSecDriverBindingSupported (
@retval EFI_SUCCES This driver is added to ControllerHandle
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.
Currently not implemented.
@retval other This driver does not support this device
@ -67,10 +94,59 @@ IpSecDriverBindingStart (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
EFI_IPSEC_PROTOCOL *IpSec;
EFI_STATUS Status;
EFI_STATUS Udp4Status;
EFI_STATUS Udp6Status;
IPSEC_PRIVATE_DATA *Private;
//
//TODO: Add Udp4Io and Udp6Io creation for the IKE.
// Ipsec protocol should be installed when load image.
//
return EFI_SUCCESS;
Status = gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &IpSec);
if (EFI_ERROR (Status)) {
return Status;
}
Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);
//
// If udp4 sb is on the controller, try to open a udp4 io for input.
//
Udp4Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUdp4ServiceBindingProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Udp4Status)) {
Udp4Status = IkeOpenInputUdp4 (Private, ControllerHandle);
}
//
// If udp6 sb is on the controller, try to open a udp6 io for input.
//
Udp6Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUdp6ServiceBindingProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Udp6Status)) {
Udp6Status = IkeOpenInputUdp6 (Private, ControllerHandle);
}
if (!EFI_ERROR (Udp4Status) || !EFI_ERROR (Udp6Status)) {
return EFI_SUCCESS;
}
return EFI_DEVICE_ERROR;
}
/**
@ -95,10 +171,78 @@ IpSecDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_IPSEC_PROTOCOL *IpSec;
EFI_STATUS Status;
IPSEC_PRIVATE_DATA *Private;
IKE_UDP_SERVICE *UdpSrv;
LIST_ENTRY *Entry;
LIST_ENTRY *Next;
//
//TODO: Add UdpIo4 and UdpIo6 destruction when the Udp driver unload or stop.
// Locate ipsec protocol to get private data.
//
return EFI_UNSUPPORTED;
Status = gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &IpSec);
if (EFI_ERROR (Status)) {
return Status;
}
Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);
//
// If has udp4 io opened on the controller, close and free it.
//
NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp4List) {
UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
//
// Find the right udp service which installed on the appointed nic handle.
//
if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {
UdpIoFreeIo (UdpSrv->Input);
UdpSrv->Input = NULL;
}
if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {
UdpIoFreeIo (UdpSrv->Output);
UdpSrv->Output = NULL;
}
if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {
RemoveEntryList (&UdpSrv->List);
FreePool (UdpSrv);
ASSERT (Private->Udp4Num > 0);
Private->Udp4Num--;
}
}
//
// If has udp6 io opened on the controller, close and free it.
//
NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp6List) {
UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
//
// Find the right udp service which installed on the appointed nic handle.
//
if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {
UdpIoFreeIo (UdpSrv->Input);
UdpSrv->Input = NULL;
}
if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {
UdpIoFreeIo (UdpSrv->Output);
UdpSrv->Output = NULL;
}
if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {
RemoveEntryList (&UdpSrv->List);
FreePool (UdpSrv);
ASSERT (Private->Udp6Num > 0);
Private->Udp6Num--;
}
}
return EFI_SUCCESS;
}
EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding = {
@ -112,9 +256,9 @@ EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding = {
/**
This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
@param[in] Context Pointer to the notification function's context.
**/
VOID
@ -125,34 +269,17 @@ IpSecCleanupAllSa (
)
{
IPSEC_PRIVATE_DATA *Private;
UINT8 Value;
EFI_STATUS Status;
Private = (IPSEC_PRIVATE_DATA *) Context;
//
// Set the Status Variable
//
Value = IPSEC_STATUS_DISABLED;
Status = gRT->SetVariable (
IPSECCONFIG_STATUS_NAME,
&gEfiIpSecConfigProtocolGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (Value),
&Value
);
if (!EFI_ERROR (Status)) {
Private->IpSec.DisabledFlag = TRUE;
}
Private = (IPSEC_PRIVATE_DATA *) Context;
Private->IsIPsecDisabling = TRUE;
IkeDeleteAllSas (Private);
}
/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
both device drivers and bus drivers.
The entry point for IPsec driver which installs the driver binding,
The entry point for IPsec driver which installs the driver binding,
component name protocol, IPsec Config protcolon, and IPsec protocol in
its ImageHandle.
@ -162,7 +289,7 @@ IpSecCleanupAllSa (
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_ALREADY_STARTED The IPsec driver has been already loaded.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
@retval Others The operation is failed.
@retval Others The operation is failed.
**/
EFI_STATUS
@ -174,7 +301,7 @@ IpSecDriverEntryPoint (
{
EFI_STATUS Status;
IPSEC_PRIVATE_DATA *Private;
EFI_IPSEC2_PROTOCOL *IpSec;
EFI_IPSEC_PROTOCOL *IpSec;
//
// Check whether ipsec protocol has already been installed.
@ -202,7 +329,7 @@ IpSecDriverEntryPoint (
goto ON_EXIT;
}
//
// Create disable event to cleanup all sa when ipsec disabled by user.
// Create disable event to cleanup all SA when ipsec disabled by user.
//
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
@ -218,8 +345,8 @@ IpSecDriverEntryPoint (
Private->Signature = IPSEC_PRIVATE_DATA_SIGNATURE;
Private->ImageHandle = ImageHandle;
CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC2_PROTOCOL));
CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC_PROTOCOL));
//
// Initilize Private's members. Thess members is used for IKE.
//
@ -229,7 +356,8 @@ IpSecDriverEntryPoint (
InitializeListHead (&Private->Ikev1EstablishedList);
InitializeListHead (&Private->Ikev2SessionList);
InitializeListHead (&Private->Ikev2EstablishedList);
RandomSeed (NULL, 0);
//
// Initialize the ipsec config data and restore it from variable.
//
@ -260,11 +388,17 @@ IpSecDriverEntryPoint (
&gIpSecComponentName2
);
if (EFI_ERROR (Status)) {
goto ON_UNINSTALL_CONFIG;
goto ON_UNINSTALL_IPSEC;
}
return Status;
ON_UNINSTALL_IPSEC:
gBS->UninstallProtocolInterface (
Private->Handle,
&gEfiIpSecProtocolGuid,
&Private->IpSec
);
ON_UNINSTALL_CONFIG:
gBS->UninstallProtocolInterface (
Private->Handle,

View File

@ -19,6 +19,7 @@
FILE_GUID = EE8367C0-A1D6-4565-8F89-EF628547B722
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = IpSecDriverEntryPoint
#
@ -34,15 +35,36 @@
IpSecCryptIo.c
IpSecDebug.h
ComponentName.c
IkeCommon.h
IpSecImpl.c
IkeService.c
Ike.h
IkePacket.h
IkePacket.c
IpSecDebug.c
IpSecSaEngine.c
IpSecMain.c
IpSecDriver.c
IkeCommon.c
IetfConstants.c
IpSecImpl.h
IkeService.h
Ikev2/Ikev2.h
Ikev2/Payload.h
Ikev2/Utility.h
Ikev2/Utility.c
Ikev2/Sa.c
Ikev2/ChildSa.c
Ikev2/Info.c
Ikev2/Payload.c
Ikev2/Exchange.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
CryptoPkg/CryptoPkg.dec
LocalNetworkPkg/LocalNetworkPkg.dec
[LibraryClasses]
MemoryAllocationLib
@ -54,10 +76,30 @@
BaseMemoryLib
DebugLib
PrintLib
#CryptLib
BaseCryptLib
DpcLib
NetLib
UdpIoLib
NetLib
PcdLib
[Protocols]
gEfiIp4ConfigProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUdp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUdp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiIpSecConfigProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiIpSecProtocolGuid # PROTOCOL ALWAYS_PRODUCED
[Pcd]
gEfiNetworkPkgTokenSpaceGuid.PcdIpsecCertiifcateEnabled
gEfiMdeModulePkgTokenSpaceGuid.UefiCaFile
gEfiMdeModulePkgTokenSpaceGuid.UefiCaFileSize
gEfiMdeModulePkgTokenSpaceGuid.UefiCertificate
gEfiMdeModulePkgTokenSpaceGuid.UefiCertificateSize
gEfiMdeModulePkgTokenSpaceGuid.UefiCertificateKey
gEfiMdeModulePkgTokenSpaceGuid.UefiCertificateKeySize
[BuildOptions.common]
#DEBUG_MYTOOLS_IA32_CC_FLAGS = /Od /GL

File diff suppressed because it is too large Load Diff

View File

@ -121,6 +121,14 @@ typedef struct _IPSEC_RECYCLE_CONTEXT {
UINT8 *PayloadBuffer;
} IPSEC_RECYCLE_CONTEXT;
//
// Struct used to store the Hash and its data.
//
typedef struct {
UINTN DataSize;
UINT8 *Data;
} HASH_DATA_FRAGMENT;
struct _IPSEC_PRIVATE_DATA {
UINT32 Signature;
EFI_HANDLE Handle; // Virtual handle to install private prtocol
@ -142,37 +150,37 @@ struct _IPSEC_PRIVATE_DATA {
/**
This function processes the inbound traffic with IPsec.
It checks the received packet security property, trims the ESP/AH header, and then
It checks the received packet security property, trims the ESP/AH header, and then
returns without an IPsec protected IP Header and FragmentTable.
@param[in] IpVersion The version of IP.
@param[in, out] IpHead Points to IP header containing the ESP/AH header
@param[in, out] IpHead Points to IP header containing the ESP/AH header
to be trimed on input, and without ESP/AH header
on return.
@param[out] LastHead The Last Header in IP header on return.
@param[in, out] LastHead The Last Header in IP header on return.
@param[in, out] OptionsBuffer Pointer to the options buffer. It is optional.
@param[in, out] OptionsLength Length of the options buffer. It is optional.
@param[in, out] FragmentTable Pointer to a list of fragments in the form of IPsec
@param[in, out] FragmentTable Pointer to a list of fragments in form of IPsec
protected on input, and without IPsec protected
on return.
@param[in, out] FragmentCount Number of fragments.
@param[in, out] FragmentCount The number of fragments.
@param[out] SpdEntry Pointer to contain the address of SPD entry on return.
@param[out] RecycleEvent Event for recycling of resources.
@param[out] RecycleEvent The event for recycling of resources.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_UNSUPPORTED If the IPSEC protocol is not supported.
@retval EFI_SUCCESS The operation was successful.
@retval EFI_UNSUPPORTED The IPSEC protocol is not supported.
**/
EFI_STATUS
IpSecProtectInboundPacket (
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
OUT UINT8 *LastHead,
IN OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer, OPTIONAL
IN OUT UINT32 *OptionsLength, OPTIONAL
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
OUT IPSEC_SPD_ENTRY **SpdEntry,
OUT EFI_IPSEC_SPD_SELECTOR **SpdEntry,
OUT EFI_EVENT *RecycleEvent
);
@ -250,11 +258,75 @@ IpSecLookupPadEntry (
IN EFI_IP_ADDRESS *IpAddr
);
/**
Check if the specified IP packet can be serviced by this SPD entry.
@param[in] SpdEntry Point to SPD entry.
@param[in] IpVersion Version of IP.
@param[in] IpHead Point to IP header.
@param[in] IpPayload Point to IP payload.
@param[in] Protocol The Last protocol of IP packet.
@param[in] IsOutbound Traffic direction.
@param[out] Action The support action of SPD entry.
@retval EFI_SUCCESS Find the related SPD.
@retval EFI_NOT_FOUND Not find the related SPD entry;
**/
EFI_STATUS
IpSecLookupSpdEntry (
IN IPSEC_SPD_ENTRY *SpdEntry,
IN UINT8 IpVersion,
IN VOID *IpHead,
IN UINT8 *IpPayload,
IN UINT8 Protocol,
IN BOOLEAN IsOutbound,
OUT EFI_IPSEC_ACTION *Action
);
/**
Look up if there is existing SAD entry for specified IP packet sending.
This function is called by the IPsecProcess when there is some IP packet needed to
send out. This function checks if there is an existing SAD entry that can be serviced
to this IP packet sending. If no existing SAD entry could be used, this
function will invoke an IPsec Key Exchange Negotiation.
@param[in] Private Points to private data.
@param[in] NicHandle Points to a NIC handle.
@param[in] IpVersion The version of IP.
@param[in] IpHead The IP Header of packet to be sent out.
@param[in] IpPayload The IP Payload to be sent out.
@param[in] OldLastHead The Last protocol of the IP packet.
@param[in] SpdEntry Points to a related SPD entry.
@param[out] SadEntry Contains the Point of a related SAD entry.
@retval EFI_DEVICE_ERROR One of following conditions is TRUE:
- If don't find related UDP service.
- Sequence Number is used up.
- Extension Sequence Number is used up.
@retval EFI_NOT_READY No existing SAD entry could be used.
@retval EFI_SUCCESS Find the related SAD entry.
**/
EFI_STATUS
IpSecLookupSadEntry (
IN IPSEC_PRIVATE_DATA *Private,
IN EFI_HANDLE NicHandle,
IN UINT8 IpVersion,
IN VOID *IpHead,
IN UINT8 *IpPayload,
IN UINT8 OldLastHead,
IN IPSEC_SPD_ENTRY *SpdEntry,
OUT IPSEC_SAD_ENTRY **SadEntry
);
/**
Find the SAD through whole SAD list.
@param[in] Spi The SPI used to search the SAD entry.
@param[in] DestAddress The destination used to search the SAD entry.
@param[in] IpVersion The IP version. Ip4 or Ip6.
@return The pointer to a certain SAD entry.
@ -262,7 +334,8 @@ IpSecLookupPadEntry (
IPSEC_SAD_ENTRY *
IpSecLookupSadBySpi (
IN UINT32 Spi,
IN EFI_IP_ADDRESS *DestAddress
IN EFI_IP_ADDRESS *DestAddress,
IN UINT8 IpVersion
)
;

View File

@ -0,0 +1,235 @@
/** @file
The mian interface of IPsec Protocol.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IpSecConfigImpl.h"
#include "IpSecImpl.h"
EFI_IPSEC2_PROTOCOL mIpSecInstance = { IpSecProcess, NULL, TRUE };
/**
Handles IPsec packet processing for inbound and outbound IP packets.
The EFI_IPSEC_PROCESS process routine handles each inbound or outbound packet.
The behavior is that it can perform one of the following actions:
bypass the packet, discard the packet, or protect the packet.
@param[in] This Pointer to the EFI_IPSEC_PROTOCOL instance.
@param[in] NicHandle Instance of the network interface.
@param[in] IpVersion IPV4 or IPV6.
@param[in, out] IpHead Pointer to the IP Header.
@param[in, out] LastHead The protocol of the next layer to be processed by IPsec.
@param[in, out] OptionsBuffer Pointer to the options buffer.
@param[in, out] OptionsLength Length of the options buffer.
@param[in, out] FragmentTable Pointer to a list of fragments.
@param[in, out] FragmentCount Number of fragments.
@param[in] TrafficDirection Traffic direction.
@param[out] RecycleSignal Event for recycling of resources.
@retval EFI_SUCCESS The packet was bypassed and all buffers remain the same.
@retval EFI_SUCCESS The packet was protected.
@retval EFI_ACCESS_DENIED The packet was discarded.
**/
EFI_STATUS
EFIAPI
IpSecProcess (
IN EFI_IPSEC2_PROTOCOL *This,
IN EFI_HANDLE NicHandle,
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
IN OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer,
IN OUT UINT32 *OptionsLength,
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection,
OUT EFI_EVENT *RecycleSignal
)
{
IPSEC_PRIVATE_DATA *Private;
IPSEC_SPD_ENTRY *SpdEntry;
EFI_IPSEC_SPD_SELECTOR *SpdSelector;
IPSEC_SAD_ENTRY *SadEntry;
LIST_ENTRY *SpdList;
LIST_ENTRY *Entry;
EFI_IPSEC_ACTION Action;
EFI_STATUS Status;
UINT8 *IpPayload;
UINT8 OldLastHead;
BOOLEAN IsOutbound;
Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (This);
IpPayload = (*FragmentTable)[0].FragmentBuffer;
IsOutbound = (BOOLEAN) ((TrafficDirection == EfiIPsecOutBound) ? TRUE : FALSE);
OldLastHead = *LastHead;
*RecycleSignal = NULL;
SpdList = &mConfigData[IPsecConfigDataTypeSpd];
if (!IsOutbound) {
//
// For inbound traffic, process the ipsec header of the packet.
//
Status = IpSecProtectInboundPacket (
IpVersion,
IpHead,
LastHead,
OptionsBuffer,
OptionsLength,
FragmentTable,
FragmentCount,
&SpdSelector,
RecycleSignal
);
if (Status == EFI_ACCESS_DENIED || Status == EFI_OUT_OF_RESOURCES) {
//
// The packet is denied to access.
//
goto ON_EXIT;
}
if (Status == EFI_SUCCESS) {
//
// Check the spd entry if the packet is accessible.
//
if (SpdSelector == NULL) {
Status = EFI_ACCESS_DENIED;
goto ON_EXIT;
}
Status = EFI_ACCESS_DENIED;
NET_LIST_FOR_EACH (Entry, SpdList) {
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
if (IsSubSpdSelector (
(EFI_IPSEC_CONFIG_SELECTOR *) SpdSelector,
(EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
)) {
Status = EFI_SUCCESS;
}
}
goto ON_EXIT;
}
}
Status = EFI_ACCESS_DENIED;
NET_LIST_FOR_EACH (Entry, SpdList) {
//
// For outbound and non-ipsec Inbound traffic: check the spd entry.
//
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
if (EFI_ERROR (IpSecLookupSpdEntry (
SpdEntry,
IpVersion,
IpHead,
IpPayload,
OldLastHead,
IsOutbound,
&Action
))) {
//
// If the related SPD not find
//
continue;
}
switch (Action) {
case EfiIPsecActionProtect:
if (IsOutbound) {
//
// For outbound traffic, lookup the sad entry.
//
Status = IpSecLookupSadEntry (
Private,
NicHandle,
IpVersion,
IpHead,
IpPayload,
OldLastHead,
SpdEntry,
&SadEntry
);
if (SadEntry != NULL) {
//
// Process the packet by the found sad entry.
//
Status = IpSecProtectOutboundPacket (
IpVersion,
IpHead,
LastHead,
OptionsBuffer,
OptionsLength,
FragmentTable,
FragmentCount,
SadEntry,
RecycleSignal
);
} else if (OldLastHead == IP6_ICMP && *IpPayload != ICMP_V6_ECHO_REQUEST) {
//
// TODO: if no need return not ready to upper layer, change here.
//
Status = EFI_SUCCESS;
}
} else if (OldLastHead == IP6_ICMP && *IpPayload != ICMP_V6_ECHO_REQUEST) {
//
// For inbound icmpv6 traffic except ping request, accept the packet
// although no sad entry associated with protect spd entry.
//
Status = IpSecLookupSadEntry (
Private,
NicHandle,
IpVersion,
IpHead,
IpPayload,
OldLastHead,
SpdEntry,
&SadEntry
);
if (SadEntry == NULL) {
Status = EFI_SUCCESS;
}
}
goto ON_EXIT;
case EfiIPsecActionBypass:
Status = EFI_SUCCESS;
goto ON_EXIT;
case EfiIPsecActionDiscard:
goto ON_EXIT;
}
}
//
// If don't find the related SPD entry, return the EFI_ACCESS_DENIED and discard it.
// But it the packet is NS/NA, it should be by passed even not find the related SPD entry.
//
if (OldLastHead == IP6_ICMP &&
(*IpPayload == ICMP_V6_NEIGHBOR_SOLICIT || *IpPayload == ICMP_V6_NEIGHBOR_ADVERTISE)
){
Status = EFI_SUCCESS;
}
ON_EXIT:
return Status;
}

View File

@ -1,934 +0,0 @@
/** @file
IPsec inbound and outbound traffic processing.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IpSecImpl.h"
#include "IpSecDebug.h"
#include "IpSecCryptIo.h"
extern LIST_ENTRY mConfigData[IPsecConfigDataTypeMaximum];
/**
The call back function of NetbufFromExt.
@param[in] Arg The argument passed from the caller.
**/
VOID
EFIAPI
IpSecOnRecyclePacket (
IN VOID *Arg
)
{
}
/**
This is a Notification function. It is called when the related IP6_TXTOKEN_WRAP
is released.
@param[in] Event The related event.
@param[in] Context The data passed by the caller.
**/
VOID
EFIAPI
IpSecRecycleCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
IPSEC_RECYCLE_CONTEXT *RecycleContext;
RecycleContext = (IPSEC_RECYCLE_CONTEXT *) Context;
if (RecycleContext->FragmentTable != NULL) {
FreePool (RecycleContext->FragmentTable);
}
if (RecycleContext->PayloadBuffer != NULL) {
FreePool (RecycleContext->PayloadBuffer);
}
FreePool (RecycleContext);
gBS->CloseEvent (Event);
}
/**
Calculate the extension header of IP. The return length only doesn't contain
the fixed IP header length.
@param[in] IpHead Points to an IP head to be calculated.
@param[in] LastHead Points to the last header of the IP header.
@return The length of the extension header.
**/
UINT16
IpSecGetPlainExtHeadSize (
IN VOID *IpHead,
IN UINT8 *LastHead
)
{
UINT16 Size;
Size = (UINT16) (LastHead - (UINT8 *) IpHead);
if (Size > sizeof (EFI_IP6_HEADER)) {
//
// * (LastHead+1) point the last header's length but not include the first
// 8 octers, so this formluation add 8 at the end.
//
Size = (UINT16) (Size - sizeof (EFI_IP6_HEADER) + *(LastHead + 1) + 8);
} else {
Size = 0;
}
return Size;
}
/**
Authenticate the IpSec Payload and store the result in the IcvBuffer.
@param[in] BufferToAuth The buffer to be Authenticated.
@param[in] AuthSize The size of the buffer to be Authenticated.
@param[in, out] IcvBuffer The buffer to store the ICV.
@param[in] IcvSize The size of ICV.
@param[in] Key The Key passed to the CryptLib to generate a
CRYPT_HANDLE.
@param[in] AuthAlgId The Authentication Algorithm ID.
@retval EFI_UNSUPPORTED If the AuthAlg is not in the support list.
@retval EFI_SUCCESS Authenticated the payload successfully.
@retval otherwise Authentication of the payload failed.
**/
EFI_STATUS
IpSecAuthPayload (
IN UINT8 *BufferToAuth,
IN UINTN AuthSize,
IN OUT UINT8 *IcvBuffer,
IN UINTN IcvSize,
IN VOID *Key,
IN UINT8 AuthAlgId
)
{
switch (AuthAlgId) {
case IKE_AALG_NONE :
case IKE_AALG_NULL :
return EFI_SUCCESS;
default:
return EFI_UNSUPPORTED;
}
}
/**
Verify if the Authentication payload is correct.
@param[in] EspBuffer Points to the ESP wrapped buffer.
@param[in] EspSize The size of the ESP wrapped buffer.
@param[in] SadEntry The related SAD entry to store the authentication
algorithm key.
@param[in] IcvSize The length of ICV.
@retval EFI_SUCCESS The authentication data is correct.
@retval EFI_ACCESS_DENIED The authentication data is not correct.
**/
EFI_STATUS
IpSecEspAuthVerifyPayload (
IN UINT8 *EspBuffer,
IN UINTN EspSize,
IN IPSEC_SAD_ENTRY *SadEntry,
IN UINTN *IcvSize
)
{
EFI_STATUS Status;
UINTN AuthSize;
UINT8 IcvBuffer[12];
//
// Calculate the size of authentication payload.
//
*IcvSize = IpSecGetIcvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId);
AuthSize = EspSize - *IcvSize;
//
// Calculate the icv buffer and size of the payload.
//
Status = IpSecAuthPayload (
EspBuffer,
AuthSize,
IcvBuffer,
*IcvSize,
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Compare the calculated icv and the appended original icv.
//
if (CompareMem (EspBuffer + AuthSize, IcvBuffer, *IcvSize) == 0) {
return EFI_SUCCESS;
}
DEBUG ((DEBUG_ERROR, "Error auth verify payload\n"));
return EFI_ACCESS_DENIED;
}
/**
ESP Decrypt the payload.
@param[in, out] PayloadBuffer Pointer to the buffer containing the ESP wrapped;
to be decrypted on input, and plaintext on return. The
number of bytes of data to be decrypted is
specified by EncryptSize.
@param[in] EncryptSize The size of the PayloadBuffer as input.
@param[in] SadEntry The related SAD entry.
@param[in] IvSize The size of IV.
@param[out] PlainPayloadSize Contains the return value of decrypted size.
@param[out] PaddingSize Contains the return value of Padding size.
@param[out] NextHeader Contains the return value of the last protocol header
of the IP packet.
@retval EFI_UNSUPPORTED The Algorithm pointed to by the SAD entry is not supported.
@retval EFI_SUCCESS The operation completed successfully.
**/
EFI_STATUS
IpSecEspDecryptPayload (
IN OUT UINT8 *PayloadBuffer,
IN UINTN EncryptSize,
IN IPSEC_SAD_ENTRY *SadEntry,
IN UINTN *IvSize,
OUT UINTN *PlainPayloadSize,
OUT UINTN *PaddingSize,
OUT UINT8 *NextHeader
)
{
EFI_ESP_TAIL *EspTail;
switch (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId) {
case IKE_EALG_NULL:
EspTail = (EFI_ESP_TAIL *) (PayloadBuffer + EncryptSize - sizeof (EFI_ESP_TAIL));
*PaddingSize = EspTail->PaddingLength;
*NextHeader = EspTail->NextHeader;
*PlainPayloadSize = EncryptSize - EspTail->PaddingLength - sizeof (EFI_ESP_TAIL);
break;
case IKE_EALG_3DESCBC:
case IKE_EALG_AESCBC:
//
// TODO: support these algorithm
//
return EFI_UNSUPPORTED;
default :
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
}
/**
ESP Encrypt the payload.
@param[in, out] BufferToEncrypt Pointer to the buffer containing plaintext to be
encrypted on input, and ciphertext on return. The
number of bytes of data to be encrypted is
specified by EncryptSize.
@param[in, out] EncryptSize The size of the plaintext on input, and the size of the
ciphertext on return.
@param[in] IvBuffer Points to IV data.
@param[in] IvSize Size of IV.
@param[in] SadEntry Related SAD entry.
@retval EFI_UNSUPPORTED The Algorithm pointed by SAD entry is not supported.
@retval EFI_SUCCESS The operation completed successfully.
**/
EFI_STATUS
IpSecEspEncryptPayload (
IN OUT UINT8 *BufferToEncrypt,
IN OUT UINTN EncryptSize,
IN UINT8 *IvBuffer,
IN UINTN IvSize,
IN IPSEC_SAD_ENTRY *SadEntry
)
{
switch (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId) {
case IKE_EALG_NULL:
return EFI_SUCCESS;
case IKE_EALG_3DESCBC:
case IKE_EALG_AESCBC:
//
// TODO: support these algorithms
//
return EFI_UNSUPPORTED;
default :
return EFI_UNSUPPORTED;
}
}
/**
The actual entry to relative function processes the inbound traffic of ESP header.
This function is the subfunction of IpSecProtectInboundPacket(). It checks the
received packet security property and trim the ESP header and then returns without
an IPsec protected IP Header and FramgmentTable.
@param[in] IpVersion The version of IP.
@param[in, out] IpHead Points to the IP header containing the ESP header
to be trimed on input, and without ESP header
on return.
@param[out] LastHead The Last Header in IP header on return.
@param[in, out] OptionsBuffer Pointer to the options buffer. It is optional.
@param[in, out] OptionsLength Length of the options buffer. It is optional.
@param[in, out] FragmentTable Pointer to a list of fragments in the form of IPsec
protected on input, and without IPsec protected
on return.
@param[in, out] FragmentCount The number of fragments.
@param[out] SpdEntry Pointer to contain the address of SPD entry on return.
@param[out] RecycleEvent The event for recycling of resources.
@retval EFI_SUCCESS The operation was successful.
@retval EFI_ACCESS_DENIED One or more following conditions is TRUE:
- ESP header was not found.
- The related SAD entry was not found.
- The related SAD entry does not support the ESP protocol.
@retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated.
**/
EFI_STATUS
IpSecEspInboundPacket (
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer, OPTIONAL
IN OUT UINT32 *OptionsLength, OPTIONAL
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
OUT IPSEC_SPD_ENTRY **SpdEntry,
OUT EFI_EVENT *RecycleEvent
)
{
EFI_STATUS Status;
NET_BUF *Payload;
UINTN EspSize;
UINTN IvSize;
UINTN PlainPayloadSize;
UINTN PaddingSize;
UINTN IcvSize;
UINT8 *ProcessBuffer;
EFI_IP_ADDRESS DestIp;
EFI_ESP_HEADER *EspHeader;
EFI_ESP_TAIL *EspTail;
EFI_IPSEC_SA_ID *SaId;
IPSEC_SAD_DATA *SadData;
IPSEC_SAD_ENTRY *SadEntry;
IPSEC_RECYCLE_CONTEXT *RecycleContext;
UINT32 Spi;
UINT8 NextHeader;
UINT16 IpSecHeadSize;
Status = EFI_SUCCESS;
Payload = NULL;
ProcessBuffer = NULL;
RecycleContext = NULL;
*RecycleEvent = NULL;
PlainPayloadSize = 0;
NextHeader = 0;
//
// Build netbuf from fragment table first.
//
Payload = NetbufFromExt (
(NET_FRAGMENT *) *FragmentTable,
*FragmentCount,
0,
sizeof (EFI_ESP_HEADER),
IpSecOnRecyclePacket,
NULL
);
if (Payload == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
//
// Get the esp size and eso header from netbuf.
//
EspSize = Payload->TotalSize;
EspHeader = (EFI_ESP_HEADER *) NetbufGetByte (Payload, 0, NULL);
if (EspHeader == NULL) {
Status = EFI_ACCESS_DENIED;
goto ON_EXIT;
}
//
// Parse destination address from ip header.
//
ZeroMem (&DestIp, sizeof (EFI_IP_ADDRESS));
if (IpVersion == IP_VERSION_4) {
CopyMem (
&DestIp,
&((IP4_HEAD *) IpHead)->Dst,
sizeof (IP4_ADDR)
);
} else {
CopyMem (
&DestIp,
&((EFI_IP6_HEADER *) IpHead)->DestinationAddress,
sizeof (EFI_IPv6_ADDRESS)
);
}
//
// Lookup sad entry according to the spi and dest address.
//
Spi = NTOHL (EspHeader->Spi);
SadEntry = IpSecLookupSadBySpi (Spi, &DestIp);
if (SadEntry == NULL) {
Status = EFI_ACCESS_DENIED;
goto ON_EXIT;
}
SaId = SadEntry->Id;
SadData = SadEntry->Data;
//
// Only support esp protocol currently.
//
if (SaId->Proto != EfiIPsecESP) {
Status = EFI_ACCESS_DENIED;
goto ON_EXIT;
}
if (!SadData->ManualSet) {
//
// TODO: Check sa lifetime and sequence number
//
}
//
// Allocate buffer for decryption and authentication by esp.
//
ProcessBuffer = AllocateZeroPool (EspSize);
if (ProcessBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
NetbufCopy (Payload, 0, (UINT32) EspSize, ProcessBuffer);
//
// Authenticate the esp wrapped buffer by the sad entry if has auth key.
//
IcvSize = 0;
if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
Status = IpSecEspAuthVerifyPayload (
ProcessBuffer,
EspSize,
SadEntry,
&IcvSize
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
}
//
// Decrypt the payload by the sad entry if has decrypt key.
//
IvSize = 0;
if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
Status = IpSecEspDecryptPayload (
ProcessBuffer + sizeof (EFI_ESP_HEADER),
EspSize - sizeof (EFI_ESP_HEADER) - IcvSize,
SadEntry,
&IvSize,
&PlainPayloadSize,
&PaddingSize,
&NextHeader
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
} else {
EspTail = (EFI_ESP_TAIL *) (ProcessBuffer + EspSize - IcvSize - sizeof (EFI_ESP_TAIL));
PaddingSize = EspTail->PaddingLength;
NextHeader = EspTail->NextHeader;
PlainPayloadSize = EspSize - sizeof (EFI_ESP_HEADER) - IvSize - IcvSize - sizeof (EFI_ESP_TAIL) - PaddingSize;
}
//
// TODO: handle anti-replay window
//
//
// Decryption and authentication with esp has been done, so it's time to
// reload the new packet, create recycle event and fixup ip header.
//
RecycleContext = AllocateZeroPool (sizeof (IPSEC_RECYCLE_CONTEXT));
if (RecycleContext == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
IpSecRecycleCallback,
RecycleContext,
RecycleEvent
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
//
// TODO: Who take responsible to handle the original fragment table?
//
*FragmentTable = AllocateZeroPool (sizeof (EFI_IPSEC_FRAGMENT_DATA));
if (*FragmentTable == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
RecycleContext->PayloadBuffer = ProcessBuffer;
RecycleContext->FragmentTable = *FragmentTable;
(*FragmentTable)[0].FragmentBuffer = ProcessBuffer + sizeof (EFI_ESP_HEADER) + IvSize;
(*FragmentTable)[0].FragmentLength = (UINT32) PlainPayloadSize;
*FragmentCount = 1;
//
// Update the total length field in ip header since processed by esp.
//
if (IpVersion == IP_VERSION_4) {
((IP4_HEAD *) IpHead)->TotalLen = HTONS ((UINT16) (((IP4_HEAD *) IpHead)->HeadLen + PlainPayloadSize));
} else {
IpSecHeadSize = IpSecGetPlainExtHeadSize (IpHead, LastHead);
((EFI_IP6_HEADER *) IpHead)->PayloadLength = HTONS ((UINT16)(IpSecHeadSize + PlainPayloadSize));
}
//
// Update the next layer field in ip header since esp header inserted.
//
*LastHead = NextHeader;
//
// Update the spd association of the sad entry.
//
*SpdEntry = SadData->SpdEntry;
ON_EXIT:
if (Payload != NULL) {
NetbufFree (Payload);
}
if (EFI_ERROR (Status)) {
if (ProcessBuffer != NULL) {
FreePool (ProcessBuffer);
}
if (RecycleContext != NULL) {
FreePool (RecycleContext);
}
if (*RecycleEvent != NULL) {
gBS->CloseEvent (*RecycleEvent);
}
}
return Status;
}
/**
The actual entry to the relative function processes the output traffic using the ESP protocol.
This function is the subfunction of IpSecProtectOutboundPacket(). It protected
the sending packet by encrypting its payload and inserting ESP header in the orginal
IP header, then return the IpHeader and IPsec protected Fragmentable.
@param[in] IpVersion The version of IP.
@param[in, out] IpHead Points to IP header containing the orginal IP header
to be processed on input, and inserted ESP header
on return.
@param[in, out] LastHead The Last Header in IP header.
@param[in, out] OptionsBuffer Pointer to the options buffer. It is optional.
@param[in, out] OptionsLength Length of the options buffer. It is optional.
@param[in, out] FragmentTable Pointer to a list of fragments to be protected by
IPsec on input, and with IPsec protected
on return.
@param[in, out] FragmentCount The number of fragments.
@param[in] SadEntry The related SAD entry.
@param[out] RecycleEvent The event for recycling of resources.
@retval EFI_SUCCESS The operation was successful.
@retval EFI_OUT_OF_RESOURCES The required system resources can't be allocated.
**/
EFI_STATUS
IpSecEspOutboundPacket (
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
IN OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer, OPTIONAL
IN OUT UINT32 *OptionsLength, OPTIONAL
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
IN IPSEC_SAD_ENTRY *SadEntry,
OUT EFI_EVENT *RecycleEvent
)
{
EFI_STATUS Status;
UINTN Index;
EFI_IPSEC_SA_ID *SaId;
IPSEC_SAD_DATA *SadData;
IPSEC_RECYCLE_CONTEXT *RecycleContext;
UINT8 *ProcessBuffer;
UINTN BytesCopied;
INTN EncryptBlockSize;// Size of encryption block, 4 bytes aligned and >= 4
UINTN EspSize; // Total size of esp wrapped ip payload
UINTN IvSize; // Size of IV, optional, might be 0
UINTN PlainPayloadSize;// Original IP payload size
UINTN PaddingSize; // Size of padding
UINTN EncryptSize; // Size of data to be encrypted, start after IV and
// stop before ICV
UINTN IcvSize; // Size of ICV, optional, might be 0
UINT8 *RestOfPayload; // Start of Payload after IV
UINT8 *Padding; // Start address of padding
EFI_ESP_HEADER *EspHeader; // Start address of ESP frame
EFI_ESP_TAIL *EspTail; // Address behind padding
Status = EFI_ACCESS_DENIED;
SaId = SadEntry->Id;
SadData = SadEntry->Data;
ProcessBuffer = NULL;
RecycleContext = NULL;
*RecycleEvent = NULL;
if (!SadData->ManualSet &&
SadData->AlgoInfo.EspAlgoInfo.EncKey == NULL &&
SadData->AlgoInfo.EspAlgoInfo.AuthKey == NULL
) {
//
// Invalid manual sad entry configuration.
//
goto ON_EXIT;
}
//
// Calculate enctrypt block size, need iv by default and 4 bytes alignment.
//
EncryptBlockSize = 4;
if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
EncryptBlockSize = IpSecGetEncryptBlockSize (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);
if (EncryptBlockSize < 0 || (EncryptBlockSize != 1 && EncryptBlockSize % 4 != 0)) {
goto ON_EXIT;
}
}
//
// Calculate the plain payload size accroding to the fragment table.
//
PlainPayloadSize = 0;
for (Index = 0; Index < *FragmentCount; Index++) {
PlainPayloadSize += (*FragmentTable)[Index].FragmentLength;
}
//
// Calculate icv size, optional by default and 4 bytes alignment.
//
IcvSize = 0;
if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
IcvSize = IpSecGetIcvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId);
if (IcvSize % 4 != 0) {
goto ON_EXIT;
}
}
//
// Calcuate the total size of esp wrapped ip payload.
//
IvSize = IpSecGetEncryptIvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);
EncryptSize = (PlainPayloadSize + sizeof (EFI_ESP_TAIL) + EncryptBlockSize - 1) / EncryptBlockSize * EncryptBlockSize;
PaddingSize = EncryptSize - PlainPayloadSize - sizeof (EFI_ESP_TAIL);
EspSize = sizeof (EFI_ESP_HEADER) + IvSize + EncryptSize + IcvSize;
ProcessBuffer = AllocateZeroPool (EspSize);
if (ProcessBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
//
// Calculate esp header and esp tail including header, payload and padding.
//
EspHeader = (EFI_ESP_HEADER *) ProcessBuffer;
RestOfPayload = (UINT8 *) (EspHeader + 1) + IvSize;
Padding = RestOfPayload + PlainPayloadSize;
EspTail = (EFI_ESP_TAIL *) (Padding + PaddingSize);
//
// Fill the sn and spi fields in esp header.
//
EspHeader->SequenceNumber = HTONL ((UINT32) SadData->SequenceNumber + 1);
EspHeader->Spi = HTONL (SaId->Spi);
//
// Copy the rest of payload (after iv) from the original fragment buffer.
//
BytesCopied = 0;
for (Index = 0; Index < *FragmentCount; Index++) {
CopyMem (
(RestOfPayload + BytesCopied),
(*FragmentTable)[Index].FragmentBuffer,
(*FragmentTable)[Index].FragmentLength
);
BytesCopied += (*FragmentTable)[Index].FragmentLength;
}
//
// Fill the padding buffer by natural number sequence.
//
for (Index = 0; Index < PaddingSize; Index++) {
Padding[Index] = (UINT8) (Index + 1);
}
//
// Fill the padding length and next header fields in esp tail.
//
EspTail->PaddingLength = (UINT8) PaddingSize;
EspTail->NextHeader = *LastHead;
//
// Generate iv at random by crypt library.
//
Status = IpSecGenerateIv (
(UINT8 *) (EspHeader + 1),
IvSize
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
//
// Encrypt the payload (after iv) by the sad entry if has encrypt key.
//
if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
Status = IpSecEspEncryptPayload (
RestOfPayload,
EncryptSize,
(UINT8 *) (EspHeader + 1),
IvSize,
SadEntry
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
}
//
// Authenticate the esp wrapped buffer by the sad entry if has auth key.
//
if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
Status = IpSecAuthPayload (
ProcessBuffer,
EspSize - IcvSize,
ProcessBuffer + EspSize - IcvSize,
IcvSize,
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
}
//
// Encryption and authentication with esp has been done, so it's time to
// reload the new packet, create recycle event and fixup ip header.
//
RecycleContext = AllocateZeroPool (sizeof (IPSEC_RECYCLE_CONTEXT));
if (RecycleContext == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
IpSecRecycleCallback,
RecycleContext,
RecycleEvent
);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
//
// TODO: Who take responsible to handle the original fragment table?
//
*FragmentTable = AllocateZeroPool (sizeof (EFI_IPSEC_FRAGMENT_DATA));
if (*FragmentTable == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
RecycleContext->FragmentTable = *FragmentTable;
RecycleContext->PayloadBuffer = ProcessBuffer;
(*FragmentTable)[0].FragmentBuffer = ProcessBuffer;
(*FragmentTable)[0].FragmentLength = (UINT32) EspSize;
*FragmentCount = 1;
//
// Update the total length field in ip header since processed by esp.
//
if (IpVersion == IP_VERSION_4) {
((IP4_HEAD *) IpHead)->TotalLen = HTONS ((UINT16) (((IP4_HEAD *) IpHead)->HeadLen + EspSize));
} else {
((EFI_IP6_HEADER *) IpHead)->PayloadLength = (UINT16) (IpSecGetPlainExtHeadSize (IpHead, LastHead) + EspSize);
}
//
// Update the next layer field in ip header since esp header inserted.
//
*LastHead = IPSEC_ESP_PROTOCOL;
//
// Increase the sn number in sad entry according to rfc4303.
//
SadData->SequenceNumber++;
ON_EXIT:
if (EFI_ERROR (Status)) {
if (ProcessBuffer != NULL) {
FreePool (ProcessBuffer);
}
if (RecycleContext != NULL) {
FreePool (RecycleContext);
}
if (*RecycleEvent != NULL) {
gBS->CloseEvent (*RecycleEvent);
}
}
return Status;
}
/**
This function processes the inbound traffic with IPsec.
It checks the received packet security property, trims the ESP/AH header, and then
returns without an IPsec protected IP Header and FragmentTable.
@param[in] IpVersion The version of IP.
@param[in, out] IpHead Points to IP header containing the ESP/AH header
to be trimed on input, and without ESP/AH header
on return.
@param[out] LastHead The Last Header in IP header on return.
@param[in, out] OptionsBuffer Pointer to the options buffer. It is optional.
@param[in, out] OptionsLength Length of the options buffer. It is optional.
@param[in, out] FragmentTable Pointer to a list of fragments in the form of IPsec
protected on input, and without IPsec protected
on return.
@param[in, out] FragmentCount Number of fragments.
@param[out] SpdEntry Pointer to contain the address of SPD entry on return.
@param[out] RecycleEvent Event for recycling of resources.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_UNSUPPORTED If the IPSEC protocol is not supported.
**/
EFI_STATUS
IpSecProtectInboundPacket (
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer, OPTIONAL
IN OUT UINT32 *OptionsLength, OPTIONAL
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
OUT IPSEC_SPD_ENTRY **SpdEntry,
OUT EFI_EVENT *RecycleEvent
)
{
if (*LastHead == IPSEC_ESP_PROTOCOL) {
//
// Process the esp ipsec header of the inbound traffic.
//
return IpSecEspInboundPacket (
IpVersion,
IpHead,
LastHead,
OptionsBuffer,
OptionsLength,
FragmentTable,
FragmentCount,
SpdEntry,
RecycleEvent
);
}
//
// The other protocols are not supported.
//
return EFI_UNSUPPORTED;
}
/**
This fucntion processes the output traffic with IPsec.
It protected the sending packet by encrypting it payload and inserting ESP/AH header
in the orginal IP header, then return the IpHeader and IPsec protected Fragmentable.
@param[in] IpVersion The version of IP.
@param[in, out] IpHead Point to IP header containing the orginal IP header
to be processed on input, and inserted ESP/AH header
on return.
@param[in, out] LastHead The Last Header in IP header.
@param[in, out] OptionsBuffer Pointer to the options buffer. It is optional.
@param[in, out] OptionsLength Length of the options buffer. It is optional.
@param[in, out] FragmentTable Pointer to a list of fragments to be protected by
IPsec on input, and with IPsec protected
on return.
@param[in, out] FragmentCount Number of fragments.
@param[in] SadEntry Related SAD entry.
@param[out] RecycleEvent Event for recycling of resources.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_UNSUPPORTED If the IPSEC protocol is not supported.
**/
EFI_STATUS
IpSecProtectOutboundPacket (
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
IN OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer, OPTIONAL
IN OUT UINT32 *OptionsLength, OPTIONAL
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
IN IPSEC_SAD_ENTRY *SadEntry,
OUT EFI_EVENT *RecycleEvent
)
{
if (SadEntry->Id->Proto == EfiIPsecESP) {
//
// Process the esp ipsec header of the outbound traffic.
//
return IpSecEspOutboundPacket (
IpVersion,
IpHead,
LastHead,
OptionsBuffer,
OptionsLength,
FragmentTable,
FragmentCount,
SadEntry,
RecycleEvent
);
}
//
// The other protocols are not supported.
//
return EFI_UNSUPPORTED;
}

View File

@ -19,3 +19,19 @@
PACKAGE_NAME = NetworkPkg
PACKAGE_GUID = 947988BE-8D5C-471a-893D-AD181C46BEBB
PACKAGE_VERSION = 0.92
[Guids]
## LocalNetwork package token space guid
# Include/Guid/NetworkPkgTokenSpace.h
gEfiNetworkPkgTokenSpaceGuid = { 0x40e064b2, 0x0ae0, 0x48b1, { 0xa0, 0x7d, 0xf8, 0xcf, 0x1e, 0x1a, 0x23, 0x10}}
[PcdsFeatureFlag]
gEfiNetworkPkgTokenSpaceGuid.PcdIpsecCertiifcateEnabled|TRUE|BOOLEAN|0x00000001
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.UefiCaFile|{0x30, 0x82, 0x02, 0x76, 0x30, 0x82, 0x01, 0xDF, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x80, 0x1D, 0xB9, 0x63, 0x93, 0x7C, 0x9D, 0xE0, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x74, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x4D, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x48, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x0D, 0x74, 0x65, 0x73, 0x74, 0x40, 0x63, 0x65, 0x72, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31, 0x35, 0x33, 0x33, 0x37, 0x5A, 0x17, 0x0D, 0x31, 0x31, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31, 0x35, 0x33, 0x33, 0x37, 0x5A, 0x30, 0x74, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x4D, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x48, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x0D, 0x74, 0x65, 0x73, 0x74, 0x40, 0x63, 0x65, 0x72, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xFC, 0x80, 0x5D, 0x32, 0x55, 0xC7, 0x4C, 0xC6, 0xA8, 0x2F, 0xF7, 0xEC, 0x1F, 0x75, 0x48, 0x02, 0x79, 0xEB, 0xDF, 0x17, 0x1B, 0x08, 0xBA, 0x21, 0xDD, 0xE5, 0x43, 0x06, 0xE8, 0x81, 0xC5, 0x50, 0x3C, 0x18, 0xDD, 0x53, 0xF4, 0xC9, 0xC9, 0xE1, 0x7A, 0xD3, 0xB3, 0x99, 0xA7, 0xC6, 0x43, 0x2A, 0x51, 0x65, 0x10, 0x93, 0xBA, 0x5F, 0x48, 0xAC, 0x54, 0x12, 0x70, 0x9E, 0xF2, 0x9E, 0x7D, 0xF7, 0x22, 0xAA, 0xB7, 0x19, 0xDE, 0xA9, 0x4D, 0x55, 0xAA, 0x41, 0x8F, 0x08, 0xBD, 0x74, 0xFA, 0xE5, 0x57, 0x13, 0xB4, 0x30, 0x9A, 0xBA, 0x56, 0x01, 0x55, 0x8A, 0x9B, 0x5B, 0x50, 0x29, 0x82, 0xF9, 0x00, 0x69, 0x7E, 0x7B, 0x91, 0xA7, 0x2D, 0x48, 0x1A, 0x93, 0x7C, 0xA2, 0xF9, 0x06, 0x64, 0x4B, 0x80, 0xF8, 0x47, 0x58, 0x45, 0x90, 0x09, 0xEA, 0xD6, 0x7B, 0x85, 0x49, 0x2A, 0x4E, 0xB6, 0x71, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x10, 0x30, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0xEF, 0x38, 0x6A, 0x43, 0x1C, 0x1D, 0x37, 0xBD, 0xF7, 0xCF, 0x15, 0x6A, 0x99, 0x44, 0xE1, 0xFC, 0x68, 0x6E, 0x91, 0x31, 0x9C, 0x1E, 0x8C, 0x1F, 0x72, 0x4B, 0x93, 0x16, 0x1F, 0x06, 0xFE, 0x94, 0xA9, 0x41, 0x64, 0x81, 0xFD, 0xFF, 0xE7, 0x27, 0x4D, 0xE7, 0x59, 0x55, 0xE1, 0x20, 0x14, 0x07, 0x3C, 0x26, 0x78, 0xB0, 0x72, 0x48, 0x76, 0x0C, 0x8B, 0x3F, 0x08, 0xD0, 0x75, 0x7D, 0x76, 0xA4, 0xB5, 0x56, 0xA6, 0xC9, 0x88, 0x17, 0x27, 0x95, 0x85, 0xEE, 0x42, 0x1E, 0x15, 0x0B, 0x05, 0xDC, 0x2F, 0x97, 0x7B, 0x26, 0x82, 0x62, 0x23, 0xDF, 0xBF, 0x55, 0x09, 0xBF, 0x5E, 0x28, 0x1A, 0xCA, 0x1B, 0xEC, 0xA4, 0x81, 0xB7, 0x9D, 0x91, 0xC9, 0x60, 0x5B, 0x29, 0x2B, 0x4C, 0x6F, 0x8B, 0xCC, 0x17, 0xA8, 0xD6, 0x5D, 0x6B, 0xBC, 0x0D, 0x03, 0x31, 0xB0, 0x57, 0xC9, 0xF8, 0x59, 0x88, 0x3D}|VOID*|0x00000001
gEfiMdeModulePkgTokenSpaceGuid.UefiCaFileSize|0x0000027A|UINT32|0x00000002
gEfiMdeModulePkgTokenSpaceGuid.UefiCertificate|{0x30, 0x82, 0x02, 0x4D, 0x30, 0x82, 0x01, 0xB6, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x74, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x4D, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x48, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x0D, 0x74, 0x65, 0x73, 0x74, 0x40, 0x63, 0x65, 0x72, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x34, 0x35, 0x39, 0x5A, 0x17, 0x0D, 0x31, 0x31, 0x31, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x34, 0x35, 0x39, 0x5A, 0x30, 0x6A, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x55, 0x45, 0x46, 0x49, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x53, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4E, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x14, 0x75, 0x65, 0x66, 0x69, 0x2E, 0x74, 0x69, 0x61, 0x6E, 0x6F, 0x40, 0x69, 0x6E, 0x74, 0x65, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x03, 0x53, 0x53, 0x47, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x03, 0x53, 0x53, 0x47, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xE9, 0x90, 0x47, 0x0D, 0x79, 0x93, 0xED, 0xF5, 0xBD, 0xC9, 0x56, 0x03, 0xDF, 0xE2, 0x71, 0xA9, 0x42, 0x3B, 0x20, 0x1E, 0xAF, 0x88, 0x9D, 0x3F, 0xE1, 0xDE, 0x61, 0xEE, 0x83, 0xC4, 0x2E, 0x48, 0x7A, 0x1F, 0x86, 0x54, 0xD2, 0xD5, 0x61, 0x94, 0xE1, 0x15, 0x79, 0x65, 0xCB, 0x39, 0xEE, 0x78, 0x68, 0x3D, 0x2C, 0xEB, 0xE4, 0x7A, 0x8D, 0x98, 0x14, 0x28, 0x7E, 0x6B, 0xFD, 0xC5, 0xF5, 0x1B, 0x62, 0xB9, 0x86, 0x7C, 0xA1, 0x7C, 0xE9, 0x8F, 0xC8, 0xF4, 0xF3, 0x95, 0x5A, 0xAF, 0x0C, 0x21, 0x39, 0xEA, 0x47, 0x5A, 0x1E, 0xBD, 0xBE, 0x7F, 0x1B, 0x0F, 0x31, 0xFB, 0xBD, 0x57, 0xAE, 0xD7, 0xCB, 0x46, 0x83, 0x8B, 0x16, 0x19, 0x74, 0xD9, 0x9E, 0x2D, 0x18, 0xE6, 0xA4, 0x5F, 0x90, 0x90, 0x54, 0xE1, 0x4B, 0x7B, 0x57, 0x76, 0xBD, 0xF4, 0xC0, 0x4D, 0x79, 0x5F, 0x64, 0x6C, 0x0D, 0x2D, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x5A, 0x80, 0x5F, 0xD3, 0x3C, 0x93, 0x81, 0xB9, 0x1B, 0xAA, 0x08, 0x1F, 0x47, 0x9C, 0x88, 0xF3, 0x1E, 0xE6, 0x6B, 0xBB, 0x99, 0xE6, 0x23, 0x1A, 0xCB, 0x25, 0x81, 0x54, 0x51, 0x88, 0xDF, 0x9B, 0xC6, 0xBF, 0x60, 0xDB, 0x6C, 0x5D, 0x69, 0xB1, 0x3A, 0xDE, 0x94, 0xEE, 0xD7, 0x6C, 0xF2, 0x2D, 0x63, 0xD3, 0xB3, 0xAB, 0xE6, 0xB5, 0x0A, 0xBF, 0xCE, 0x61, 0xC0, 0xD3, 0x73, 0x9E, 0x80, 0xB5, 0x0C, 0xC0, 0x03, 0x57, 0xA9, 0x56, 0x59, 0x1B, 0xA2, 0x99, 0x03, 0xA6, 0xA3, 0xC4, 0x59, 0xB3, 0xD9, 0x14, 0xA1, 0x34, 0x18, 0xF3, 0x73, 0xB8, 0x54, 0xAA, 0xED, 0x7D, 0x31, 0x3E, 0x23, 0xAD, 0xF1, 0x86, 0xF7, 0xE6, 0xD9, 0x01, 0x0D, 0x68, 0xC6, 0xC5, 0x95, 0x18, 0xD2, 0x89, 0xB7, 0x06, 0x96, 0xC9, 0x11, 0xB9, 0xF0, 0xDA, 0xD9, 0x02, 0x25, 0xC4, 0xB9, 0x72, 0xF8, 0x6D, 0xC5, 0x5B}|VOID*|0x00000003
gEfiMdeModulePkgTokenSpaceGuid.UefiCertificateSize|0x251|UINT32|0x00000004
gEfiMdeModulePkgTokenSpaceGuid.UefiCertificateKey|{0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x50, 0x72, 0x6F, 0x63, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x34, 0x2C, 0x45, 0x4E, 0x43, 0x52, 0x59, 0x50, 0x54, 0x45, 0x44, 0x0A, 0x44, 0x45, 0x4B, 0x2D, 0x49, 0x6E, 0x66, 0x6F, 0x3A, 0x20, 0x44, 0x45, 0x53, 0x2D, 0x45, 0x44, 0x45, 0x33, 0x2D, 0x43, 0x42, 0x43, 0x2C, 0x32, 0x42, 0x31, 0x46, 0x42, 0x41, 0x43, 0x41, 0x38, 0x36, 0x32, 0x36, 0x33, 0x34, 0x41, 0x37, 0x0A, 0x0A, 0x61, 0x52, 0x78, 0x49, 0x58, 0x33, 0x59, 0x4D, 0x68, 0x49, 0x50, 0x41, 0x73, 0x59, 0x79, 0x6F, 0x6A, 0x49, 0x76, 0x46, 0x7A, 0x42, 0x75, 0x6B, 0x74, 0x6B, 0x4A, 0x47, 0x5A, 0x38, 0x4D, 0x64, 0x33, 0x5A, 0x53, 0x73, 0x39, 0x41, 0x2B, 0x52, 0x2B, 0x57, 0x45, 0x59, 0x41, 0x70, 0x34, 0x63, 0x4F, 0x55, 0x43, 0x4A, 0x78, 0x51, 0x2F, 0x66, 0x4A, 0x38, 0x58, 0x4F, 0x45, 0x64, 0x58, 0x38, 0x0A, 0x31, 0x63, 0x4E, 0x66, 0x4B, 0x2B, 0x49, 0x62, 0x76, 0x4B, 0x4D, 0x68, 0x55, 0x67, 0x30, 0x4B, 0x4E, 0x35, 0x38, 0x37, 0x71, 0x66, 0x2F, 0x4C, 0x31, 0x76, 0x57, 0x58, 0x6F, 0x31, 0x74, 0x5A, 0x6B, 0x59, 0x2B, 0x5A, 0x53, 0x4E, 0x63, 0x46, 0x45, 0x41, 0x76, 0x37, 0x43, 0x43, 0x50, 0x51, 0x6B, 0x64, 0x4A, 0x42, 0x48, 0x35, 0x65, 0x6B, 0x35, 0x44, 0x51, 0x2F, 0x37, 0x6D, 0x71, 0x55, 0x0A, 0x6B, 0x76, 0x78, 0x48, 0x53, 0x50, 0x70, 0x34, 0x66, 0x41, 0x71, 0x47, 0x61, 0x68, 0x54, 0x31, 0x75, 0x37, 0x37, 0x56, 0x66, 0x4E, 0x66, 0x31, 0x53, 0x74, 0x61, 0x73, 0x31, 0x6E, 0x4F, 0x67, 0x6A, 0x50, 0x31, 0x41, 0x6C, 0x7A, 0x6E, 0x6B, 0x6A, 0x57, 0x61, 0x72, 0x6A, 0x51, 0x4F, 0x73, 0x48, 0x46, 0x33, 0x41, 0x46, 0x31, 0x62, 0x61, 0x51, 0x4A, 0x50, 0x5A, 0x31, 0x6A, 0x71, 0x4C, 0x0A, 0x61, 0x30, 0x49, 0x45, 0x6E, 0x30, 0x6C, 0x59, 0x6C, 0x78, 0x35, 0x79, 0x4D, 0x6D, 0x78, 0x54, 0x47, 0x57, 0x79, 0x52, 0x35, 0x70, 0x57, 0x51, 0x35, 0x71, 0x66, 0x78, 0x2B, 0x62, 0x37, 0x64, 0x37, 0x75, 0x71, 0x67, 0x47, 0x69, 0x66, 0x36, 0x6A, 0x44, 0x47, 0x4D, 0x37, 0x68, 0x38, 0x43, 0x78, 0x2F, 0x74, 0x67, 0x2B, 0x61, 0x62, 0x45, 0x31, 0x34, 0x30, 0x2F, 0x50, 0x66, 0x6C, 0x33, 0x0A, 0x33, 0x6A, 0x50, 0x6C, 0x52, 0x75, 0x73, 0x57, 0x6F, 0x6F, 0x63, 0x49, 0x41, 0x76, 0x49, 0x74, 0x79, 0x51, 0x6D, 0x39, 0x39, 0x71, 0x74, 0x34, 0x64, 0x6E, 0x74, 0x6E, 0x74, 0x6F, 0x4A, 0x43, 0x6D, 0x4F, 0x53, 0x79, 0x71, 0x67, 0x4D, 0x6E, 0x76, 0x2F, 0x76, 0x2B, 0x51, 0x48, 0x74, 0x79, 0x4D, 0x73, 0x42, 0x64, 0x38, 0x34, 0x78, 0x45, 0x57, 0x46, 0x36, 0x72, 0x58, 0x4D, 0x52, 0x63, 0x0A, 0x53, 0x2B, 0x66, 0x68, 0x54, 0x71, 0x58, 0x74, 0x54, 0x38, 0x44, 0x50, 0x65, 0x70, 0x2F, 0x56, 0x44, 0x66, 0x65, 0x78, 0x6B, 0x41, 0x63, 0x6D, 0x63, 0x75, 0x41, 0x69, 0x6F, 0x2B, 0x79, 0x64, 0x51, 0x75, 0x49, 0x31, 0x32, 0x7A, 0x50, 0x70, 0x45, 0x68, 0x50, 0x45, 0x68, 0x31, 0x44, 0x50, 0x58, 0x73, 0x64, 0x58, 0x67, 0x64, 0x77, 0x39, 0x75, 0x46, 0x47, 0x6D, 0x63, 0x35, 0x68, 0x52, 0x0A, 0x35, 0x31, 0x57, 0x41, 0x31, 0x65, 0x63, 0x44, 0x48, 0x6A, 0x31, 0x58, 0x32, 0x45, 0x72, 0x36, 0x39, 0x59, 0x70, 0x31, 0x50, 0x69, 0x43, 0x37, 0x49, 0x47, 0x79, 0x6F, 0x71, 0x57, 0x43, 0x37, 0x69, 0x2F, 0x71, 0x6D, 0x6D, 0x72, 0x49, 0x66, 0x6F, 0x41, 0x54, 0x74, 0x39, 0x58, 0x34, 0x30, 0x54, 0x56, 0x63, 0x37, 0x42, 0x63, 0x6A, 0x34, 0x63, 0x54, 0x31, 0x78, 0x37, 0x6B, 0x70, 0x4F, 0x0A, 0x4C, 0x71, 0x67, 0x33, 0x6C, 0x50, 0x78, 0x33, 0x2B, 0x4A, 0x63, 0x33, 0x43, 0x67, 0x34, 0x79, 0x5A, 0x54, 0x66, 0x6E, 0x4A, 0x5A, 0x37, 0x48, 0x76, 0x36, 0x64, 0x68, 0x67, 0x45, 0x6D, 0x70, 0x4D, 0x73, 0x74, 0x46, 0x65, 0x35, 0x34, 0x49, 0x53, 0x76, 0x74, 0x38, 0x37, 0x59, 0x4E, 0x77, 0x74, 0x4C, 0x65, 0x6C, 0x34, 0x67, 0x50, 0x4A, 0x79, 0x53, 0x42, 0x30, 0x4B, 0x76, 0x37, 0x69, 0x0A, 0x33, 0x32, 0x74, 0x37, 0x67, 0x4F, 0x30, 0x79, 0x6D, 0x73, 0x62, 0x71, 0x4A, 0x55, 0x75, 0x79, 0x41, 0x68, 0x47, 0x64, 0x33, 0x63, 0x2B, 0x78, 0x4C, 0x46, 0x2F, 0x63, 0x63, 0x4F, 0x57, 0x44, 0x52, 0x34, 0x79, 0x72, 0x30, 0x6A, 0x79, 0x64, 0x74, 0x70, 0x79, 0x69, 0x64, 0x52, 0x45, 0x66, 0x56, 0x46, 0x66, 0x5
3, 0x6C, 0x39, 0x54, 0x30, 0x6D, 0x53, 0x72, 0x4E, 0x76, 0x43, 0x71, 0x45, 0x0A, 0x52, 0x52, 0x5A, 0x6E, 0x42, 0x56, 0x76, 0x37, 0x50, 0x66, 0x6C, 0x75, 0x72, 0x31, 0x59, 0x35, 0x70, 0x2F, 0x65, 0x78, 0x54, 0x63, 0x56, 0x34, 0x72, 0x4B, 0x52, 0x69, 0x6C, 0x35, 0x58, 0x6A, 0x2F, 0x39, 0x59, 0x56, 0x31, 0x4E, 0x6E, 0x6D, 0x4E, 0x2B, 0x2F, 0x31, 0x31, 0x74, 0x36, 0x58, 0x74, 0x6A, 0x72, 0x75, 0x52, 0x62, 0x33, 0x79, 0x70, 0x38, 0x76, 0x64, 0x6C, 0x61, 0x65, 0x5A, 0x0A, 0x6C, 0x67, 0x45, 0x69, 0x73, 0x30, 0x42, 0x7A, 0x4B, 0x59, 0x39, 0x59, 0x64, 0x58, 0x48, 0x64, 0x46, 0x58, 0x57, 0x59, 0x4F, 0x41, 0x71, 0x50, 0x48, 0x45, 0x65, 0x4B, 0x57, 0x79, 0x61, 0x59, 0x5A, 0x56, 0x79, 0x43, 0x70, 0x51, 0x65, 0x43, 0x53, 0x71, 0x4F, 0x71, 0x48, 0x38, 0x67, 0x42, 0x6B, 0x4F, 0x62, 0x43, 0x69, 0x72, 0x41, 0x6A, 0x65, 0x56, 0x70, 0x35, 0x7A, 0x37, 0x6B, 0x31, 0x0A, 0x64, 0x4F, 0x2F, 0x6D, 0x56, 0x74, 0x49, 0x2B, 0x57, 0x47, 0x30, 0x48, 0x72, 0x37, 0x5A, 0x4C, 0x53, 0x52, 0x78, 0x6F, 0x61, 0x44, 0x47, 0x42, 0x33, 0x4E, 0x35, 0x38, 0x4B, 0x56, 0x45, 0x4F, 0x34, 0x65, 0x46, 0x56, 0x75, 0x6E, 0x59, 0x77, 0x51, 0x42, 0x54, 0x7A, 0x4F, 0x65, 0x57, 0x39, 0x6C, 0x4B, 0x79, 0x49, 0x38, 0x67, 0x4D, 0x45, 0x57, 0x6C, 0x62, 0x4B, 0x72, 0x41, 0x45, 0x49, 0x0A, 0x46, 0x4B, 0x38, 0x7A, 0x58, 0x6F, 0x44, 0x74, 0x39, 0x6A, 0x7A, 0x54, 0x37, 0x67, 0x68, 0x6A, 0x79, 0x45, 0x54, 0x67, 0x44, 0x6C, 0x69, 0x50, 0x53, 0x49, 0x46, 0x6A, 0x79, 0x31, 0x64, 0x6B, 0x6A, 0x6D, 0x68, 0x53, 0x78, 0x79, 0x6A, 0x67, 0x62, 0x71, 0x45, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A}|VOID*|0x00000005
gEfiMdeModulePkgTokenSpaceGuid.UefiCertificateKeySize|0x3d5|UINT32|0x00000006

View File

@ -42,6 +42,9 @@
NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
[LibraryClasses.common.UEFI_DRIVER]
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf