]> git.proxmox.com Git - mirror_edk2.git/blobdiff - CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
CryptoPkg/BaseCryptLib:time overflow
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / SysCall / TimerWrapper.c
index 805e6b4e206bbbec1a6114a42b33238c6cc0aad7..2dfc6fe6c5932cdb732be6df5ecbfe344b9e6e7e 100644 (file)
@@ -2,36 +2,29 @@
   C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation\r
   for OpenSSL-based Cryptographic Library (used in DXE & RUNTIME).\r
 \r
-Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <Uefi.h>\r
-#include <OpenSslSupport.h>\r
+#include <CrtLibSupport.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
 \r
 //\r
 // -- Time Management Routines --\r
 //\r
 \r
-#define IsLeap(y)   (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))\r
-#define SECSPERMIN  (60)\r
-#define SECSPERHOUR (60 * 60)\r
-#define SECSPERDAY  (24 * SECSPERHOUR)\r
+#define SECSPERMIN   (60)\r
+#define SECSPERHOUR  (60 * 60)\r
+#define SECSPERDAY   (24 * SECSPERHOUR)\r
 \r
 //\r
 //  The arrays give the cumulative number of days up to the first of the\r
 //  month number used as the index (1 -> 12) for regular and leap years.\r
 //  The value at index 13 is for the whole year.\r
 //\r
-UINTN CumulativeDays[2][14] = {\r
+UINTN  CumulativeDays[2][14] = {\r
   {\r
     0,\r
     0,\r
@@ -62,58 +55,94 @@ UINTN CumulativeDays[2][14] = {
     31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,\r
     31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,\r
     31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,\r
-    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 \r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31\r
   }\r
 };\r
 \r
+/* Check the year is leap or not. */\r
+// BOOLEAN IsLeap(\r
+//  INTN timer\r
+//  )\r
+BOOLEAN\r
+IsLeap (\r
+  time_t  timer\r
+  )\r
+{\r
+  INT64  Remainder1;\r
+  INT64  Remainder2;\r
+  INT64  Remainder3;\r
+\r
+  DivS64x64Remainder (timer, 4, &Remainder1);\r
+  DivS64x64Remainder (timer, 100, &Remainder2);\r
+  DivS64x64Remainder (timer, 400, &Remainder3);\r
+\r
+  return (Remainder1 == 0 && (Remainder2 != 0 || Remainder3 == 0));\r
+}\r
+\r
 /* Get the system time as seconds elapsed since midnight, January 1, 1970. */\r
-//INTN time(\r
+// INTN time(\r
 //  INTN *timer\r
 //  )\r
-time_t time (time_t *timer)\r
+time_t\r
+time (\r
+  time_t  *timer\r
+  )\r
 {\r
-  EFI_TIME  Time;\r
-  UINTN     Year;\r
+  EFI_STATUS  Status;\r
+  EFI_TIME    Time;\r
+  time_t      CalTime;\r
+  UINTN       Year;\r
 \r
   //\r
   // Get the current time and date information\r
   //\r
-  gRT->GetTime (&Time, NULL);\r
+  Status = gRT->GetTime (&Time, NULL);\r
+  if (EFI_ERROR (Status) || (Time.Year < 1970)) {\r
+    return 0;\r
+  }\r
 \r
   //\r
   // Years Handling\r
   // UTime should now be set to 00:00:00 on Jan 1 of the current year.\r
   //\r
-  for (Year = 1970, *timer = 0; Year != Time.Year; Year++) {\r
-    *timer = *timer + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY);\r
+  for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {\r
+    CalTime = CalTime + (time_t)(CumulativeDays[IsLeap (Year)][13] * SECSPERDAY);\r
   }\r
 \r
   //\r
   // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment\r
   //\r
-  *timer = *timer + \r
-           (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) +\r
-           (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] * SECSPERDAY) + \r
-           (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) + \r
-           (time_t)(Time.Hour * SECSPERHOUR) + \r
-           (time_t)(Time.Minute * 60) + \r
-           (time_t)Time.Second;\r
-\r
-  return *timer;\r
+  CalTime = CalTime +\r
+            (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) +\r
+            (time_t)(CumulativeDays[IsLeap (Time.Year)][Time.Month] * SECSPERDAY) +\r
+            (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +\r
+            (time_t)(Time.Hour * SECSPERHOUR) +\r
+            (time_t)(Time.Minute * 60) +\r
+            (time_t)Time.Second;\r
+\r
+  if (timer != NULL) {\r
+    *timer = CalTime;\r
+  }\r
+\r
+  return CalTime;\r
 }\r
 \r
 //\r
 // Convert a time value from type time_t to struct tm.\r
 //\r
-struct tm * gmtime (const time_t *timer)\r
+struct tm *\r
+gmtime (\r
+  const time_t  *timer\r
+  )\r
 {\r
   struct tm  *GmTime;\r
-  UINT16     DayNo;\r
-  UINT16     DayRemainder;\r
+  UINT64     DayNo;\r
+  UINT64     DayRemainder;\r
   time_t     Year;\r
   time_t     YearNo;\r
-  UINT16     TotalDays;\r
-  UINT16     MonthNo;\r
+  UINT32     TotalDays;\r
+  UINT32     MonthNo;\r
+  INT64      Remainder;\r
 \r
   if (timer == NULL) {\r
     return NULL;\r
@@ -124,38 +153,41 @@ struct tm * gmtime (const time_t *timer)
     return NULL;\r
   }\r
 \r
-  ZeroMem ((VOID *) GmTime, (UINTN) sizeof (struct tm));\r
+  ZeroMem ((VOID *)GmTime, (UINTN)sizeof (struct tm));\r
 \r
-  DayNo        = (UINT16) (*timer / SECSPERDAY);\r
-  DayRemainder = (UINT16) (*timer % SECSPERDAY);\r
+  DayNo        = (UINT64)DivS64x64Remainder (*timer, SECSPERDAY, &Remainder);\r
+  DayRemainder = (UINT64)Remainder;\r
 \r
-  GmTime->tm_sec  = (int) (DayRemainder % SECSPERMIN);\r
-  GmTime->tm_min  = (int) ((DayRemainder % SECSPERHOUR) / SECSPERMIN);\r
-  GmTime->tm_hour = (int) (DayRemainder / SECSPERHOUR);\r
-  GmTime->tm_wday = (int) ((DayNo + 4) % 7);\r
+  DivS64x64Remainder (DayRemainder, SECSPERMIN, &Remainder);\r
+  GmTime->tm_sec = (int)Remainder;\r
+  DivS64x64Remainder (DayRemainder, SECSPERHOUR, &Remainder);\r
+  GmTime->tm_min  = (int)DivS64x64Remainder (Remainder, SECSPERMIN, NULL);\r
+  GmTime->tm_hour = (int)DivS64x64Remainder (DayRemainder, SECSPERHOUR, NULL);\r
+  DivS64x64Remainder ((DayNo + 4), 7, &Remainder);\r
+  GmTime->tm_wday = (int)Remainder;\r
 \r
   for (Year = 1970, YearNo = 0; DayNo > 0; Year++) {\r
-    TotalDays = (UINT16) (IsLeap (Year) ? 366 : 365);\r
+    TotalDays = (UINT32)(IsLeap (Year) ? 366 : 365);\r
     if (DayNo >= TotalDays) {\r
-      DayNo = (UINT16) (DayNo - TotalDays);\r
+      DayNo = (UINT64)(DayNo - TotalDays);\r
       YearNo++;\r
     } else {\r
       break;\r
     }\r
   }\r
 \r
-  GmTime->tm_year = (int) (YearNo + (1970 - 1900));\r
-  GmTime->tm_yday = (int) DayNo;\r
+  GmTime->tm_year = (int)(YearNo + (1970 - 1900));\r
+  GmTime->tm_yday = (int)DayNo;\r
 \r
   for (MonthNo = 12; MonthNo > 1; MonthNo--) {\r
-    if (DayNo > CumulativeDays[IsLeap(Year)][MonthNo]) {\r
-      DayNo = (UINT16) (DayNo - (UINT16) (CumulativeDays[IsLeap(Year)][MonthNo]));\r
+    if (DayNo >= CumulativeDays[IsLeap (Year)][MonthNo]) {\r
+      DayNo = (UINT64)(DayNo - (UINT32)(CumulativeDays[IsLeap (Year)][MonthNo]));\r
       break;\r
     }\r
   }\r
 \r
-  GmTime->tm_mon  = (int) MonthNo;\r
-  GmTime->tm_mday = (int) DayNo;\r
+  GmTime->tm_mon  = (int)MonthNo - 1;\r
+  GmTime->tm_mday = (int)DayNo + 1;\r
 \r
   GmTime->tm_isdst  = 0;\r
   GmTime->tm_gmtoff = 0;\r