Fix SmmCryptLib issue when calling time() in RealTimeClock.c

Signed-off by: Ye Ting <ting.ye@intel.com>
Reviewed-by: Yao Jiewen <jiewen.yao@intel.com>
Reviewed-by: Long Qin <qin.long@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13417 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
tye1 2012-06-01 02:37:24 +00:00
parent c4c9086678
commit 38fcd0270f
3 changed files with 51 additions and 287 deletions

View File

@ -1,6 +1,15 @@
## @file
# Cryptographic Library Instance for SMM driver.
#
# This library instance uses ConstantTimeClock.c thus does not provide
# functionality for following APIs which need system time support:
# 1) RsaGenerateKey
# 2) RsaCheckKey
# 3) RsaPkcs1Sign
# 4) Pkcs7Sign
# 5) DhGenerateParameter
# 6) DhGenerateKey
#
# Copyright (c) 2010 - 2012, 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
@ -37,7 +46,7 @@
Pem/CryptPem.c
SysCall/CrtWrapper.c
SysCall/RealTimeClock.c
SysCall/ConstantTimeClock.c
SysCall/BaseMemAllocation.c
[Sources.Ia32]

View File

@ -0,0 +1,41 @@
/** @file
C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation
for OpenSSL-based Cryptographic Library.
This C file implements constant time value for time() and NULL for gmtime()
thus should not be used in library instances which require functionality
of following APIs which need system time support:
1) RsaGenerateKey
2) RsaCheckKey
3) RsaPkcs1Sign
4) Pkcs7Sign
5) DhGenerateParameter
6) DhGenerateKey
Copyright (c) 2010 - 2012, 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 <OpenSslSupport.h>
//
// -- Time Management Routines --
//
time_t time (time_t *timer)
{
*timer = 0;
return *timer;
}
struct tm * gmtime (const time_t *timer)
{
return NULL;
}

View File

@ -1,286 +0,0 @@
/** @file
C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation
for OpenSSL-based Cryptographic Library (used in SMM).
Copyright (c) 2010 - 2011, 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 <Library/BaseLib.h>
#include <Library/IoLib.h>
#include <OpenSslSupport.h>
#define PCAT_RTC_ADDRESS_REGISTER 0x70
#define PCAT_RTC_DATA_REGISTER 0x71
#define RTC_ADDRESS_SECONDS 0 // R/W Range 0..59
#define RTC_ADDRESS_SECONDS_ALARM 1 // R/W Range 0..59
#define RTC_ADDRESS_MINUTES 2 // R/W Range 0..59
#define RTC_ADDRESS_MINUTES_ALARM 3 // R/W Range 0..59
#define RTC_ADDRESS_HOURS 4 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM
#define RTC_ADDRESS_HOURS_ALARM 5 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM
#define RTC_ADDRESS_DAY_OF_THE_WEEK 6 // R/W Range 1..7
#define RTC_ADDRESS_DAY_OF_THE_MONTH 7 // R/W Range 1..31
#define RTC_ADDRESS_MONTH 8 // R/W Range 1..12
#define RTC_ADDRESS_YEAR 9 // R/W Range 0..99
#define RTC_ADDRESS_REGISTER_A 10 // R/W[0..6] R0[7]
#define RTC_ADDRESS_REGISTER_B 11 // R/W
#define RTC_ADDRESS_REGISTER_C 12 // RO
#define RTC_ADDRESS_REGISTER_D 13 // RO
#define RTC_ADDRESS_CENTURY 50 // R/W Range 19..20 Bit 8 is R/W
//
// Register A
//
typedef struct {
UINT8 RS : 4; // Rate Selection Bits
UINT8 DV : 3; // Divisor
UINT8 UIP : 1; // Update in progress
} RTC_REGISTER_A_BITS;
typedef union {
RTC_REGISTER_A_BITS Bits;
UINT8 Data;
} RTC_REGISTER_A;
//
// Register B
//
typedef struct {
UINT8 DSE : 1; // 0 - Daylight saving disabled 1 - Daylight savings enabled
UINT8 MIL : 1; // 0 - 12 hour mode 1 - 24 hour mode
UINT8 DM : 1; // 0 - BCD Format 1 - Binary Format
UINT8 SQWE : 1; // 0 - Disable SQWE output 1 - Enable SQWE output
UINT8 UIE : 1; // 0 - Update INT disabled 1 - Update INT enabled
UINT8 AIE : 1; // 0 - Alarm INT disabled 1 - Alarm INT Enabled
UINT8 PIE : 1; // 0 - Periodic INT disabled 1 - Periodic INT Enabled
UINT8 SET : 1; // 0 - Normal operation. 1 - Updates inhibited
} RTC_REGISTER_B_BITS;
typedef union {
RTC_REGISTER_B_BITS Bits;
UINT8 Data;
} RTC_REGISTER_B;
//
// -- Time Management Routines --
//
#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#define SECSPERMIN (60)
#define SECSPERHOUR (60 * 60)
#define SECSPERDAY (24 * SECSPERHOUR)
//
// The arrays give the cumulative number of days up to the first of the
// month number used as the index (1 -> 12) for regular and leap years.
// The value at index 13 is for the whole year.
//
UINTN CumulativeDays[2][14] = {
{
0,
0,
31,
31 + 28,
31 + 28 + 31,
31 + 28 + 31 + 30,
31 + 28 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
},
{
0,
0,
31,
31 + 29,
31 + 29 + 31,
31 + 29 + 31 + 30,
31 + 29 + 31 + 30 + 31,
31 + 29 + 31 + 30 + 31 + 30,
31 + 29 + 31 + 30 + 31 + 30 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
}
};
/**
Read RTC content through its registers.
@param Address Address offset of RTC. It is recommended to use macros such as
RTC_ADDRESS_SECONDS.
@return The data of UINT8 type read from RTC.
**/
UINT8
RtcRead (
IN UINT8 Address
)
{
IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & BIT7)));
return IoRead8 (PCAT_RTC_DATA_REGISTER);
}
/* Get the system time as seconds elapsed since midnight, January 1, 1970. */
//INTN time(
// INTN *timer
// )
time_t time (time_t *timer)
{
UINT16 Year;
UINT8 Month;
UINT8 Day;
UINT8 Hour;
UINT8 Minute;
UINT8 Second;
UINT8 Century;
RTC_REGISTER_A RegisterA;
RTC_REGISTER_B RegisterB;
BOOLEAN IsPM;
UINT16 YearIndex;
RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);
while (RegisterA.Bits.UIP == 1) {
CpuPause();
RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);
}
Second = RtcRead (RTC_ADDRESS_SECONDS);
Minute = RtcRead (RTC_ADDRESS_MINUTES);
Hour = RtcRead (RTC_ADDRESS_HOURS);
Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);
Month = RtcRead (RTC_ADDRESS_MONTH);
Year = RtcRead (RTC_ADDRESS_YEAR);
Century = RtcRead (RTC_ADDRESS_CENTURY);
RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);
if ((Hour & BIT7) != 0) {
IsPM = TRUE;
} else {
IsPM = FALSE;
}
Hour = (UINT8) (Hour & 0x7f);
if (RegisterB.Bits.DM == 0) {
Year = BcdToDecimal8 ((UINT8) Year);
Month = BcdToDecimal8 (Month);
Day = BcdToDecimal8 (Day);
Hour = BcdToDecimal8 (Hour);
Minute = BcdToDecimal8 (Minute);
Second = BcdToDecimal8 (Second);
}
Century = BcdToDecimal8 (Century);
Year = (UINT16) (Century * 100 + Year);
//
// If time is in 12 hour format, convert it to 24 hour format
//
if (RegisterB.Bits.MIL == 0) {
if (IsPM && Hour < 12) {
Hour = (UINT8) (Hour + 12);
}
if (!IsPM && Hour == 12) {
Hour = 0;
}
}
//
// Years Handling
// UTime should now be set to 00:00:00 on Jan 1 of the current year.
//
for (YearIndex = 1970, *timer = 0; YearIndex != Year; YearIndex++) {
*timer = *timer + (time_t)(CumulativeDays[IsLeap(YearIndex)][13] * SECSPERDAY);
}
//
// Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment
//
ASSERT (Month <= 12);
*timer = *timer +
(time_t)(CumulativeDays[IsLeap(Year)][Month] * SECSPERDAY) +
(time_t)((Day - 1) * SECSPERDAY) +
(time_t)(Hour * SECSPERHOUR) +
(time_t)(Minute * 60) +
(time_t)Second;
return *timer;
}
//
// Convert a time value from type time_t to struct tm.
//
struct tm * gmtime (const time_t *timer)
{
struct tm *GmTime;
UINT16 DayNo;
UINT16 DayRemainder;
time_t Year;
time_t YearNo;
UINT16 TotalDays;
UINT16 MonthNo;
if (timer == NULL) {
return NULL;
}
GmTime = malloc (sizeof (struct tm));
if (GmTime == NULL) {
return NULL;
}
ZeroMem ((VOID *) GmTime, (UINTN) sizeof (struct tm));
DayNo = (UINT16) (*timer / SECSPERDAY);
DayRemainder = (UINT16) (*timer % SECSPERDAY);
GmTime->tm_sec = (int) (DayRemainder % SECSPERMIN);
GmTime->tm_min = (int) ((DayRemainder % SECSPERHOUR) / SECSPERMIN);
GmTime->tm_hour = (int) (DayRemainder / SECSPERHOUR);
GmTime->tm_wday = (int) ((DayNo + 4) % 7);
for (Year = 1970, YearNo = 0; DayNo > 0; Year++) {
TotalDays = (UINT16) (IsLeap (Year) ? 366 : 365);
if (DayNo >= TotalDays) {
DayNo = (UINT16) (DayNo - TotalDays);
YearNo++;
} else {
break;
}
}
GmTime->tm_year = (int) (YearNo + (1970 - 1900));
GmTime->tm_yday = (int) DayNo;
for (MonthNo = 12; MonthNo > 1; MonthNo--) {
if (DayNo > CumulativeDays[IsLeap(Year)][MonthNo]) {
DayNo = (UINT16) (DayNo - (UINT16) (CumulativeDays[IsLeap(Year)][MonthNo]));
break;
}
}
GmTime->tm_mon = (int) MonthNo;
GmTime->tm_mday = (int) DayNo;
GmTime->tm_isdst = 0;
GmTime->tm_gmtoff = 0;
GmTime->tm_zone = NULL;
return GmTime;
}