[openfirmware] [commit] r2198 - cpu/x86/pc/olpc

repository service svn at openfirmware.info
Fri May 13 00:09:18 CEST 2011


Author: wmb
Date: Fri May 13 00:09:17 2011
New Revision: 2198
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2198

Log:
OLPC RTC anti-rollback - working version.

Modified:
   cpu/x86/pc/olpc/guardrtc.fth
   cpu/x86/pc/olpc/security.fth

Modified: cpu/x86/pc/olpc/guardrtc.fth
==============================================================================
--- cpu/x86/pc/olpc/guardrtc.fth	Tue May 10 19:56:01 2011	(r2197)
+++ cpu/x86/pc/olpc/guardrtc.fth	Fri May 13 00:09:17 2011	(r2198)
@@ -70,6 +70,7 @@
    flash-open           ( )
    (put-mfg-data)       ( )
    flash-close          ( )
+   d# 1000 ms           ( )  \ Give the EC time to restart
 ;
 : flash-write-some  ( adr len offset -- )
    flash-open           ( adr len offset )
@@ -142,31 +143,41 @@
    update-timestamp                         ( status )
 ;
 
-1 buffer: byte-buf
-: encode-byte  ( b -- )  byte-buf c! byte-buf 1 encode-bytes  ;
 : +encode-bytes  ( prop$ $ -- prop$' )  encode-bytes encode+  ;
 
-: make-timestamp-property  ( -- )
-   rtc-timestamp 0=  if  exit  then
-   " /chosen" find-package drop push-package  ( )
-   rtc-timestamp unix-seconds>                ( s m h d m y )
-   push-decimal                               ( s m h d m y )
-   #timestamps (.) encode-bytes               ( s m h d m y prop$ )
-   " ," +encode-bytes  rot (.4) +encode-bytes ( s m h d m prop$ )
-   " -" +encode-bytes  rot (.2) +encode-bytes ( s m h d prop$' )
-   " -" +encode-bytes  rot (.2) +encode-bytes ( s m h prop$' )
-   " @" +encode-bytes  rot (.2) +encode-bytes ( s m prop$' )
-   " :" +encode-bytes  rot (.2) +encode-bytes ( s prop$' )
-   " :" +encode-bytes  rot (.2) +encode-bytes ( prop$' )
-   " "(00)" +encode-bytes                     ( prop$' )
-   pop-base                                   ( )
-   
-   " rtc-timestamp" (property)                ( )
-   pop-package
-;
-: make-status-property  ( value$ -- )
-   " /chosen" find-package drop push-package  ( value$ )
+string-array rtc-status-names
+   ," ok"
+   ," empty"
+   ," residue"
+   ," rollback"
+end-string-array
+
+: make-rtc-properties  ( status -- )
+   " /chosen" find-package drop push-package  ( status )
+
+   rtc-status-names count
    encode-string  " rtc-status"  (property)   ( )
+
+   rtc-timestamp  if
+      rtc-timestamp unix-seconds>      ( s m h d m y )
+      push-decimal                     ( s m h d m y )
+      (.4) encode-bytes                ( s m h d m prop$ )
+      rot (.2) +encode-bytes           ( s m h d prop$' )
+      rot (.2) +encode-bytes           ( s m h prop$' )
+      " T" +encode-bytes               ( s m h prop$' )
+      rot (.2) +encode-bytes           ( s m prop$' )
+      rot (.2) +encode-bytes           ( s prop$' )
+      rot (.2) +encode-bytes           ( prop$' )
+      " Z"(00)" +encode-bytes          ( prop$' )
+      pop-base                         ( )
+
+      " rtc-timestamp" (property)      ( )
+   then
+
+   push-decimal
+   #timestamps (.) encode-bytes  " rtc-count" (property)    ( )
+   pop-base
+
    pop-package
 ;
 
@@ -178,24 +189,19 @@
    then                    ( flag )
 ;
 
-: rtc-rollback?  ( -- flag )
+: rtc-rollback?  ( -- error? )
    rtcar-enabled?  0=  if  exit  then
 
    find-timestamp            ( status )
    ?update-timestamp         ( status' )
-   make-timestamp-property   ( status )
-   case
-      0  of  " ok"        make-status-property  false  endof
-      1  of  " empty"     make-status-property  false  endof
-      2  of  " residue"   make-status-property  true   endof
-      3  of  " rollback"  make-status-property  true   endof
-      ( default )  true swap
-   endcase
+   dup make-rtc-properties   ( status )
+   2 >=                      ( error? )
 ;
 
-: parse-field  ( val$ delimiter expected-length -- val$' field$ )
-   >r  left-parse-string   ( val$' field$ )
-   dup r> <>  throw
+: parse-field  ( val$ length -- val$' field$ )
+   2dup < throw              ( val$ length )
+   >r  over r@               ( val$ adr length r: length )
+   2swap r> /string 2swap    ( val$' field$ )
 ;
 \ Throws an error if either a number is unparsable or out of range
 : decode-number  ( field$ min max -- n )
@@ -206,48 +212,47 @@
 ;
 
 : decode-timestamp  ( val$ -- s m h d m y )
-   [char] - 4 parse-field   d# 2000 d# 2099 decode-number >r   ( val$' r: y )
-   [char] - 2 parse-field  1 d# 12 decode-number >r   ( val$' r: y m )
-   [char] @ 2 parse-field  1 d# 31 decode-number >r   ( val$' r: y m d )
-   [char] : 2 parse-field  0 d# 23 decode-number >r   ( val$' r: y m d h )
-   [char] : 2 parse-field  0 d# 59 decode-number >r   ( val$' r: y m d h m )
-   dup 2 <> throw          0 d# 59 decode-number >r   ( r: y m d h m s )
-   r> r> r> r> r> r>                                  ( s m h d m y )
-;
-: fix-rtc-timestamps  ( data$ -- )  \ "count old-ts new-ts"  e.g. 2011-10-12,00:23:45
-   bl left-parse-string                       ( rem$ count$ )
-
-   0 h# 7fffffff ['] decode-number catch  if  ( rem$ x x x x )
-      4drop 2drop  ." Bad count format" cr    ( )
-      exit                                    ( -- )
-   then                                       ( rem$ count )
-   -rot                                       ( count rem$ )
-
-   find-timestamp                             ( count rem$ )
-
-   bl left-parse-string                       ( count rem$ old-timestamp$ )
-   2dup " no-timestamp" $=  if                ( count rem$ old-timestamp$ )
-      2drop                                   ( count rem$ )
-      rtc-timestamp  if                       ( count rem$ )
-	 3drop                                ( )
+   4 parse-field  d# 2000 d# 2099 decode-number >r  ( val$' r: y )
+   2 parse-field  1 d# 12 decode-number >r          ( val$' r: y m )
+   2 parse-field  1 d# 31 decode-number >r          ( val$' r: y m d )
+   1 parse-field  drop c@ [char] T <> throw         ( val$' r: y m d )
+   2 parse-field  0 d# 23 decode-number >r          ( val$' r: y m d h )
+   2 parse-field  0 d# 59 decode-number >r          ( val$' r: y m d h m )
+   2 parse-field  0 d# 59 decode-number >r          ( val$' r: y m d h m s )
+   1 parse-field  drop c@ [char] Z <> throw         ( val$' r: y m d h m s )
+   nip 0<> throw                                    ( r: y m d h m s )
+   r> r> r> r> r> r>                                ( s m h d m y )
+;
+: fix-rtc-timestamps  ( newrtc$ nonce$ -- currentrtc$ )
+   find-timestamp drop                        ( newrtc$ nonce$ currentrtc$ )
+
+   2dup " 00000000T000000Z" $=  if            ( newrtc$ nonce$ currentrtc$ )
+      2drop                                   ( newrtc$ nonce$ )
+      rtc-timestamp  if                       ( newrtc$ nonce$ )
+	 4drop                                ( )
 	 ." Old timestamp mismatch" cr        ( )
 	 exit                                 ( -- )
-      then
-   else                                       ( count rem$ old-timestamp$ )
-      ['] decode-timestamp catch  if          ( count rem$ x x )
-	 5drop                                ( )
+      then                                    ( newrtc$ nonce$ )
+   else                                       ( newrtc$ nonce$ currentrtc$ )
+      ['] decode-timestamp catch  if          ( newrtc$ nonce$ x x )
+	 2drop 4drop                          ( )
 	 ." Bad timestamp format" cr          ( )
 	 exit                                 ( -- )
-      then                                    ( count rem$ s m h d m y )
-   then                                       ( count rem$ s m h d m y )
+      then                                    ( newrtc$ nonce$ s m h d m y  )
+      >unix-seconds                           ( newrtc$ nonce$ timestamp )
+      rtc-timestamp <>  if                    ( newrtc$ nonce$ )
+         4drop                                ( )
+         ." Old timestamp mismatch" cr        ( ) 
+         exit                                 ( -- )
+      then                                    ( newrtc$ nonce$ )
+   then                                       ( newrtc$ nonce$ )
 
-   >unix-seconds                              ( count rem$ old-timestamp )
-   rtc-timestamp <>  if                       ( count rem$ )
-      3drop                                   ( )
-      ." Old timestamp mismatch" cr           ( ) 
+   0 h# 7fffffff ['] decode-number catch  if  ( newrtc$ x x x x )
+      4drop 2drop  ." Bad count format" cr    ( )
       exit                                    ( -- )
-   then                                       ( count rem$ )
-   rot init-timestamp-area                    ( rem$ )
+   then                                       ( newrtc$ count )
+
+   init-timestamp-area                        ( newrtc$ )
    
    ['] decode-timestamp catch  if             ( x x )
       2drop  ." Bad timestamp format" cr      ( )

Modified: cpu/x86/pc/olpc/security.fth
==============================================================================
--- cpu/x86/pc/olpc/security.fth	Tue May 10 19:56:01 2011	(r2197)
+++ cpu/x86/pc/olpc/security.fth	Fri May 13 00:09:17 2011	(r2198)
@@ -955,37 +955,102 @@
    r> to debug-security?
 ;
 
-: fix-rtc-history  ( data$ -- )  \ SN UUID counter timestamp newtimestamp
-   \ Isolate data from first line
+
+0 [if]
+\ SN  :   UUID     :   currrtc :   nonce    :  newrtc
+\ 0   11  12       48  49      65  66       76 77      (93)
+d# 11 1+  d# 36 +  1+  d# 16 + 1+  d# 10 +  1+ d# 16 +
+constant /rtc-signature
+/rtc-signature buffer: rtc-signature-buf
+
+: check-rtc-signature  ( sig$ currentrtc$ nonce$ newrtc$ -- good? )
+
+   rtc-signature-buf d# 77 +  swap move       ( sig$ currentrtc$ nonce$ )
+   [char] : rtc-signature-buf d# 76 + c!      ( sig$ currentrtc$ nonce$ )
+
+   rtc-signature-buf d# 66 +  swap move       ( sig$ currentrtc$ )
+   [char] : rtc-signature-buf d# 65 + c!      ( sig$ currentrtc$ )
+
+   rtc-signature-buf d# 49 +  swap move       ( sig$ )
+
+   \ Copy SN:UUID: from machine-id-buf to rtc-signature-buf
+   machine-id-buf  d# 49 rtc-signature-buf  move  ( sig$ )
+
+   rtc-signature-buf /rtc-signature  2swap        ( data$ sig$ )
+   " sha256" signature-good?                      ( good? )
+;
+   newrtc$  rtc-signature-buf d# 77 +  swap move       ( )
+   [char] : rtc-signature-buf d# 76 + c!              ( )
+
+   nonce$  rtc-signature-buf d# 66 +  swap move  ( )
+   [char] : rtc-signature-buf d# 65 + c!              ( )
+
+   currentrtc$  rtc-signature-buf d# 49 +  swap move      ( )
+   [char] : rtc-signature-buf d# 48 + c!              ( )
+
+[then]
+
+0 0 2value currentrtc$
+0 0 2value newrtc$
+0 0 2value nonce$
+0 0 2value rtcsig$
+: rtc-format-error  ( -- done? )
+   ." RTC Reset format error" ?lease-error-cr  true
+;
+: check-rtc-key  ( data$ -- done? )  \ rtc01: SN currentrtc nonce newrtc sig0N: ...
+   \ Isolate data from line
    newline left-parse-string 2nip              ( rem$ )
 
+   bl left-parse-string  " rtc01:" $=  0=  if  ( rem$ )
+      ." Unknown format" ?lease-error-cr       ( rem$ )
+      2drop true exit                          ( -- true )
+   then                                        ( rem$ )
+
    bl left-parse-string                        ( rem$ serial$ )
    my-sn$ $=  0=  if                           ( rem$ )
-      ." Wrong serial number" ?lease-error-cr  ( rem$ )
-      2drop exit                               ( -- )
+\     ." Wrong serial number" ?lease-error-cr  ( rem$ )
+      2drop false exit                         ( -- false )
    then                                        ( rem$ )
 
-   \ Ignore UUID for now
-   bl left-parse-string                        ( rem$ uuid$ )
-   2drop                                       ( rem$ )
-
-   fix-rtc-timestamps                          ( )
+   bl left-parse-string to currentrtc$         ( rem$' )
+   bl left-parse-string to nonce$              ( rem$' )
+   bl left-parse-string to newrtc$             ( rem$' )
+   to rtcsig$                                  ( )
+
+   currentrtc$ nip d# 16 <>  if  rtc-format-error  exit  then
+   nonce$      nip d# 10 <>  if  rtc-format-error  exit  then
+   newrtc$     nip d# 16 <>  if  rtc-format-error  exit  then
+
+   newrtc$ nonce$ currentrtc$ machine-id-buf d# 48 " %s:%s:%s:%s" sprintf  ( data$ )
+
+   rtcsig$  " sha256" signature-good?   if            ( )
+      newrtc$ nonce$ currentrtc$  fix-rtc-timestamps  ( )
+   else
+      ." Bad signature " ?lease-error-cr              ( )
+   then                                               ( )
+   true                                               ( done? )
 ;
 
 : ?rtc-update  ( -- )
    rtcar-enabled?  0=  if  exit  then
    show-dot
    null$ cn-buf place
-   " rtcreset" bundle-present?  if
+   " rtcreset.sig" open-security?  if  exit  then   >r  ( r: ih )
       "   RTCRESET found - " ?lease-debug
+      load-started
       leasekey$ to pubkey$
-      img$  sig$  sha-valid?  if
-	 img$ fix-rtc-history
-         show-unlock
-      else
-	 show-lock
-      then
-   then
+   begin
+      sec-line-buf /sec-line-max r@ read-line  if  ( actual -eof? )
+         2drop  r> close-file drop  exit
+      then                                         ( actual -eof? )
+   while                                           ( actual )
+      sec-line-buf swap check-rtc-key  if          ( )
+         r> close-file drop  exit                  ( -- )
+      then                                         ( )
+   repeat                                          ( actual )
+   drop                                            ( )
+   "   No matching records" ?lease-error-cr        ( )
+   r> close-file drop  false                       ( false )
 ;
 
 : load-from-device  ( devname$ -- done? )



More information about the openfirmware mailing list