Changeset 13221 in project


Ignore:
Timestamp:
02/09/09 13:31:09 (11 years ago)
Author:
Alaric Snell-Pym
Message:

V1.1: cbc* mode

Location:
release/3/crypto-tools/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • release/3/crypto-tools/trunk/crypto-tools.scm

    r13197 r13221  
    44(declare (export
    55   blob->hexstring blob->hexstring/uppercase hexstring->blob
    6    subblob blob-xor blob-pad blob-unpad
    7    make-cbc-encryptor make-cbc-decryptor))
     6   blob-xor blob-pad blob-unpad
     7   make-cbc-encryptor make-cbc-decryptor
     8   make-cbc*-encryptor make-cbc*-decryptor))
    89
    910(define *the-null-blob* (make-blob 0))
     
    190191                      (output (make-blob inputsize)))
    191192                  (decrypt input 0 inputsize iv output 0)))))
     193
     194; As above, but the encryptor stores the IV in the output block (encrypted)...
     195
     196(define (make-cbc*-encryptor encryptor blocksize)
     197   (letrec ((encrypt (lambda (input inoffset inputsize iv output outoffset)
     198         (cond
     199            ((= inoffset inputsize) ; Zero bytes
     200               (let* ((inblock (blob-pad *the-null-blob* blocksize))
     201                      (outblock (encryptor (blob-xor iv inblock))))
     202                  (move-memory! outblock output blocksize 0 outoffset)
     203                  output)) ; Terminate
     204            ((<= (+ inoffset blocksize) inputsize) ; Just another block
     205               (let* ((inblock (subblob input inoffset blocksize))
     206                      (outblock (encryptor (blob-xor iv inblock))))
     207
     208                  (move-memory! outblock output blocksize 0 outoffset)
     209                  (encrypt input (+ inoffset blocksize) inputsize outblock output (+ outoffset blocksize)))) ; Recurse
     210            (else ; Partial block
     211               (let* ((inblock (blob-pad
     212                        (subblob input inoffset (- inputsize inoffset))
     213                        blocksize))
     214                      (outblock (encryptor (blob-xor iv inblock))))
     215
     216                  (move-memory! outblock output blocksize 0 outoffset)
     217                  output)))))) ; Terminate
     218
     219            (lambda (input iv)
     220               (let* ((inputsize (blob-size input))
     221                      (output-whole-blocks (quotient inputsize blocksize))
     222                      (output-overflow (remainder inputsize blocksize))
     223                      (outputsize (if (zero? output-overflow) ; Round up to block size, plus an extra block for the IV
     224                         (+ inputsize blocksize blocksize)
     225                         (* (+ 2 output-whole-blocks) blocksize)))
     226                      (output (make-blob outputsize))
     227                      (encrypted-iv (encryptor iv)))
     228                  (move-memory! encrypted-iv output blocksize)
     229                  (encrypt input 0 inputsize iv output blocksize)))))
     230
     231;... and the decryptor retreives it.
     232
     233(define (make-cbc*-decryptor decryptor blocksize)
     234   (letrec ((decrypt (lambda (input inoffset inputsize iv output outoffset)
     235               (if (= (+ inoffset blocksize) inputsize)
     236                  ; Last block
     237                  (let* ((inblock (subblob input inoffset blocksize))
     238                         (outblock
     239                            (blob-unpad
     240                               (blob-xor iv
     241                                 (decryptor inblock)))))
     242                        (move-memory! outblock output (blob-size outblock) 0 outoffset)
     243                        (subblob output 0 (+ outoffset (blob-size outblock)))) ; Terminate
     244                  ; Not last block
     245                  (let* ((inblock (subblob input inoffset blocksize))
     246                         (outblock
     247                            (blob-xor iv
     248                              (decryptor inblock))))
     249
     250                        (move-memory! outblock output blocksize 0 outoffset)
     251                        (decrypt input (+ inoffset blocksize) inputsize inblock output (+ outoffset blocksize))))))) ; Recurse
     252
     253            (lambda (input)
     254               (let* ((inputsize (blob-size input))
     255                      (output (make-blob inputsize))
     256                      (iv (decryptor (subblob input 0 blocksize))))
     257                  (decrypt input blocksize inputsize iv output 0)))))
  • release/3/crypto-tools/trunk/crypto-tools.setup

    r13197 r13221  
    55  'crypto-tools
    66  '("crypto-tools.o" "crypto-tools.so" "crypto-tools.html")
    7   '((version 1.0)
     7  '((version 1.1)
    88    (static "crypto-tools.o") ;; for static linking
    99    (documentation "crypto-tools.html")))
  • release/3/crypto-tools/trunk/test/run.scm

    r13197 r13221  
    3030(test-padding "4" "abcdefghijklmno")
    3131
    32 (define (dummy-encryptor l) l)
    33 (define (dummy-decryptor l) l)
     32(define dummy-key (hexstring->blob "01010101010101010101010101010101"))
     33(define (dummy-encryptor l) (blob-xor l dummy-key))
     34(define dummy-decryptor dummy-encryptor)
    3435
    3536(define (test-cbc name string)
     
    5556(test-cbc "11" "123456789012345") ; 1 block - 1
    5657(test-cbc "12" "1234567890123456123456789012345") ; 2 blocks - 1
     58
     59(define (test-cbc* name string)
     60   (let*
     61      ((encryptor dummy-encryptor)
     62       (decryptor dummy-decryptor)
     63       (cbc-encryptor (make-cbc*-encryptor encryptor 16))
     64       (cbc-decryptor (make-cbc*-decryptor decryptor 16))
     65       (test-input (string->blob string))
     66       (encrypted (cbc-encryptor test-input (hexstring->blob "00010203050607080A0B0C0D0F101112")))
     67       (decrypted (cbc-decryptor encrypted)))
     68   
     69      (printf "Test vector ~Aa: ~A\n" name (blob->hexstring/uppercase encrypted))
     70      (printf "Test vector ~Ab: <~A>\n" name (blob->string decrypted))
     71      (assert (blob=? test-input decrypted))))
     72
     73(test-cbc* "13" "") ; Zero bytes
     74(test-cbc* "14" "a") ; One byte
     75(test-cbc* "15" "1234567890123456") ; 1 block exactly
     76(test-cbc* "16" "12345678901234561234567890123456") ; 2 blocks exactly
     77(test-cbc* "17" "1234567890123456X") ; 1 block + 1
     78(test-cbc* "18" "12345678901234561234567890123456X") ; 2 blocks + 1
     79(test-cbc* "19" "123456789012345") ; 1 block - 1
     80(test-cbc* "20" "1234567890123456123456789012345") ; 2 blocks - 1
     81
Note: See TracChangeset for help on using the changeset viewer.