github.com/readium/readium-lcp-server@v0.0.0-20240101192032-6e95190e99f1/crypto/aes_gcm.go (about) 1 // Copyright (c) 2016 Readium Foundation 2 // 3 // Redistribution and use in source and binary forms, with or without modification, 4 // are permitted provided that the following conditions are met: 5 // 6 // 1. Redistributions of source code must retain the above copyright notice, this 7 // list of conditions and the following disclaimer. 8 // 2. Redistributions in binary form must reproduce the above copyright notice, 9 // this list of conditions and the following disclaimer in the documentation and/or 10 // other materials provided with the distribution. 11 // 3. Neither the name of the organization nor the names of its contributors may be 12 // used to endorse or promote products derived from this software without specific 13 // prior written permission 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26 package crypto 27 28 import ( 29 "crypto/aes" 30 "crypto/cipher" 31 "encoding/binary" 32 "io" 33 "io/ioutil" 34 ) 35 36 type gcmEncrypter struct { 37 counter uint64 38 } 39 40 func (e gcmEncrypter) Signature() string { 41 return "http://www.w3.org/2009/xmlenc11#aes256-gcm" 42 } 43 44 func (e gcmEncrypter) GenerateKey() (ContentKey, error) { 45 slice, err := GenerateKey(aes256keyLength) 46 return ContentKey(slice), err 47 } 48 49 func (e *gcmEncrypter) Encrypt(key ContentKey, r io.Reader, w io.Writer) error { 50 block, err := aes.NewCipher(key) 51 if err != nil { 52 return err 53 } 54 55 counter := e.counter 56 e.counter++ 57 58 gcm, err := cipher.NewGCM(block) 59 if err != nil { 60 return err 61 } 62 63 nonce := make([]byte, gcm.NonceSize()) 64 binary.BigEndian.PutUint64(nonce, counter) 65 66 data, err := ioutil.ReadAll(r) 67 out := gcm.Seal(nonce, nonce, data, nil) 68 69 _, err = w.Write(out) 70 71 return err 72 } 73 74 func NewAESGCMEncrypter() Encrypter { 75 return &gcmEncrypter{} 76 }