ciphers.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. // Copyright (C) 2017. See AUTHORS.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package openssl
  15. // #include "shim.h"
  16. import "C"
  17. import (
  18. "errors"
  19. "fmt"
  20. "runtime"
  21. "unsafe"
  22. )
  23. const (
  24. GCM_TAG_MAXLEN = 16
  25. )
  26. type CipherCtx interface {
  27. Cipher() *Cipher
  28. BlockSize() int
  29. KeySize() int
  30. IVSize() int
  31. }
  32. type Cipher struct {
  33. ptr *C.EVP_CIPHER
  34. }
  35. func (c *Cipher) Nid() NID {
  36. return NID(C.X_EVP_CIPHER_nid(c.ptr))
  37. }
  38. func (c *Cipher) ShortName() (string, error) {
  39. return Nid2ShortName(c.Nid())
  40. }
  41. func (c *Cipher) BlockSize() int {
  42. return int(C.X_EVP_CIPHER_block_size(c.ptr))
  43. }
  44. func (c *Cipher) KeySize() int {
  45. return int(C.X_EVP_CIPHER_key_length(c.ptr))
  46. }
  47. func (c *Cipher) IVSize() int {
  48. return int(C.X_EVP_CIPHER_iv_length(c.ptr))
  49. }
  50. func Nid2ShortName(nid NID) (string, error) {
  51. sn := C.OBJ_nid2sn(C.int(nid))
  52. if sn == nil {
  53. return "", fmt.Errorf("NID %d not found", nid)
  54. }
  55. return C.GoString(sn), nil
  56. }
  57. func GetCipherByName(name string) (*Cipher, error) {
  58. cname := C.CString(name)
  59. defer C.free(unsafe.Pointer(cname))
  60. p := C.EVP_get_cipherbyname(cname)
  61. if p == nil {
  62. return nil, fmt.Errorf("Cipher %v not found", name)
  63. }
  64. // we can consider ciphers to use static mem; don't need to free
  65. return &Cipher{ptr: p}, nil
  66. }
  67. func GetCipherByNid(nid NID) (*Cipher, error) {
  68. sn, err := Nid2ShortName(nid)
  69. if err != nil {
  70. return nil, err
  71. }
  72. return GetCipherByName(sn)
  73. }
  74. type cipherCtx struct {
  75. ctx *C.EVP_CIPHER_CTX
  76. }
  77. func newCipherCtx() (*cipherCtx, error) {
  78. cctx := C.EVP_CIPHER_CTX_new()
  79. if cctx == nil {
  80. return nil, errors.New("failed to allocate cipher context")
  81. }
  82. ctx := &cipherCtx{cctx}
  83. runtime.SetFinalizer(ctx, func(ctx *cipherCtx) {
  84. C.EVP_CIPHER_CTX_free(ctx.ctx)
  85. })
  86. return ctx, nil
  87. }
  88. func (ctx *cipherCtx) applyKeyAndIV(key, iv []byte) error {
  89. var kptr, iptr *C.uchar
  90. if key != nil {
  91. if len(key) != ctx.KeySize() {
  92. return fmt.Errorf("bad key size (%d bytes instead of %d)",
  93. len(key), ctx.KeySize())
  94. }
  95. kptr = (*C.uchar)(&key[0])
  96. }
  97. if iv != nil {
  98. if len(iv) != ctx.IVSize() {
  99. return fmt.Errorf("bad IV size (%d bytes instead of %d)",
  100. len(iv), ctx.IVSize())
  101. }
  102. iptr = (*C.uchar)(&iv[0])
  103. }
  104. if kptr != nil || iptr != nil {
  105. var res C.int
  106. if C.X_EVP_CIPHER_CTX_encrypting(ctx.ctx) != 0 {
  107. res = C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, kptr, iptr)
  108. } else {
  109. res = C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, kptr, iptr)
  110. }
  111. if 1 != res {
  112. return errors.New("failed to apply key/IV")
  113. }
  114. }
  115. return nil
  116. }
  117. func (ctx *cipherCtx) Cipher() *Cipher {
  118. return &Cipher{ptr: C.X_EVP_CIPHER_CTX_cipher(ctx.ctx)}
  119. }
  120. func (ctx *cipherCtx) BlockSize() int {
  121. return int(C.X_EVP_CIPHER_CTX_block_size(ctx.ctx))
  122. }
  123. func (ctx *cipherCtx) KeySize() int {
  124. return int(C.X_EVP_CIPHER_CTX_key_length(ctx.ctx))
  125. }
  126. func (ctx *cipherCtx) IVSize() int {
  127. return int(C.X_EVP_CIPHER_CTX_iv_length(ctx.ctx))
  128. }
  129. func (ctx *cipherCtx) setCtrl(code, arg int) error {
  130. res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), nil)
  131. if res != 1 {
  132. return fmt.Errorf("failed to set code %d to %d [result %d]",
  133. code, arg, res)
  134. }
  135. return nil
  136. }
  137. func (ctx *cipherCtx) setCtrlBytes(code, arg int, value []byte) error {
  138. res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg),
  139. unsafe.Pointer(&value[0]))
  140. if res != 1 {
  141. return fmt.Errorf("failed to set code %d with arg %d to %x [result %d]",
  142. code, arg, value, res)
  143. }
  144. return nil
  145. }
  146. func (ctx *cipherCtx) getCtrlInt(code, arg int) (int, error) {
  147. var returnVal C.int
  148. res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg),
  149. unsafe.Pointer(&returnVal))
  150. if res != 1 {
  151. return 0, fmt.Errorf("failed to get code %d with arg %d [result %d]",
  152. code, arg, res)
  153. }
  154. return int(returnVal), nil
  155. }
  156. func (ctx *cipherCtx) getCtrlBytes(code, arg, expectsize int) ([]byte, error) {
  157. returnVal := make([]byte, expectsize)
  158. res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg),
  159. unsafe.Pointer(&returnVal[0]))
  160. if res != 1 {
  161. return nil, fmt.Errorf("failed to get code %d with arg %d [result %d]",
  162. code, arg, res)
  163. }
  164. return returnVal, nil
  165. }
  166. type EncryptionCipherCtx interface {
  167. CipherCtx
  168. // pass in plaintext, get back ciphertext. can be called
  169. // multiple times as needed
  170. EncryptUpdate(input []byte) ([]byte, error)
  171. // call after all plaintext has been passed in; may return
  172. // additional ciphertext if needed to finish off a block
  173. // or extra padding information
  174. EncryptFinal() ([]byte, error)
  175. }
  176. type DecryptionCipherCtx interface {
  177. CipherCtx
  178. // pass in ciphertext, get back plaintext. can be called
  179. // multiple times as needed
  180. DecryptUpdate(input []byte) ([]byte, error)
  181. // call after all ciphertext has been passed in; may return
  182. // additional plaintext if needed to finish off a block
  183. DecryptFinal() ([]byte, error)
  184. }
  185. type encryptionCipherCtx struct {
  186. *cipherCtx
  187. }
  188. type decryptionCipherCtx struct {
  189. *cipherCtx
  190. }
  191. func newEncryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) (
  192. *encryptionCipherCtx, error) {
  193. if c == nil {
  194. return nil, errors.New("null cipher not allowed")
  195. }
  196. ctx, err := newCipherCtx()
  197. if err != nil {
  198. return nil, err
  199. }
  200. var eptr *C.ENGINE
  201. if e != nil {
  202. eptr = e.e
  203. }
  204. if 1 != C.EVP_EncryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) {
  205. return nil, errors.New("failed to initialize cipher context")
  206. }
  207. err = ctx.applyKeyAndIV(key, iv)
  208. if err != nil {
  209. return nil, err
  210. }
  211. return &encryptionCipherCtx{cipherCtx: ctx}, nil
  212. }
  213. func newDecryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) (
  214. *decryptionCipherCtx, error) {
  215. if c == nil {
  216. return nil, errors.New("null cipher not allowed")
  217. }
  218. ctx, err := newCipherCtx()
  219. if err != nil {
  220. return nil, err
  221. }
  222. var eptr *C.ENGINE
  223. if e != nil {
  224. eptr = e.e
  225. }
  226. if 1 != C.EVP_DecryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) {
  227. return nil, errors.New("failed to initialize cipher context")
  228. }
  229. err = ctx.applyKeyAndIV(key, iv)
  230. if err != nil {
  231. return nil, err
  232. }
  233. return &decryptionCipherCtx{cipherCtx: ctx}, nil
  234. }
  235. func NewEncryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) (
  236. EncryptionCipherCtx, error) {
  237. return newEncryptionCipherCtx(c, e, key, iv)
  238. }
  239. func NewDecryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) (
  240. DecryptionCipherCtx, error) {
  241. return newDecryptionCipherCtx(c, e, key, iv)
  242. }
  243. func (ctx *encryptionCipherCtx) EncryptUpdate(input []byte) ([]byte, error) {
  244. outbuf := make([]byte, len(input)+ctx.BlockSize())
  245. outlen := C.int(len(outbuf))
  246. res := C.EVP_EncryptUpdate(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen,
  247. (*C.uchar)(&input[0]), C.int(len(input)))
  248. if res != 1 {
  249. return nil, fmt.Errorf("failed to encrypt [result %d]", res)
  250. }
  251. return outbuf[:outlen], nil
  252. }
  253. func (ctx *decryptionCipherCtx) DecryptUpdate(input []byte) ([]byte, error) {
  254. outbuf := make([]byte, len(input)+ctx.BlockSize())
  255. outlen := C.int(len(outbuf))
  256. res := C.EVP_DecryptUpdate(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen,
  257. (*C.uchar)(&input[0]), C.int(len(input)))
  258. if res != 1 {
  259. return nil, fmt.Errorf("failed to decrypt [result %d]", res)
  260. }
  261. return outbuf[:outlen], nil
  262. }
  263. func (ctx *encryptionCipherCtx) EncryptFinal() ([]byte, error) {
  264. outbuf := make([]byte, ctx.BlockSize())
  265. var outlen C.int
  266. if 1 != C.EVP_EncryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) {
  267. return nil, errors.New("encryption failed")
  268. }
  269. return outbuf[:outlen], nil
  270. }
  271. func (ctx *decryptionCipherCtx) DecryptFinal() ([]byte, error) {
  272. outbuf := make([]byte, ctx.BlockSize())
  273. var outlen C.int
  274. if 1 != C.EVP_DecryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) {
  275. // this may mean the tag failed to verify- all previous plaintext
  276. // returned must be considered faked and invalid
  277. return nil, errors.New("decryption failed")
  278. }
  279. return outbuf[:outlen], nil
  280. }