  ErrorType decrypt_length(unsigned char* data,
                           size_t data_len,
                           uint32_t seqno,
                           uint32_t* packet_length) {
    ErrorType r = kErrNone;
    int outlen;

    unsigned char dec_length_bytes[4];

    uint8_t seqbuf[16] = {0};
    ((uint8_t*)(seqbuf))[12] = (seqno >> 24) & 0xff;
    ((uint8_t*)(seqbuf))[13] = (seqno >> 16) & 0xff;
    ((uint8_t*)(seqbuf))[14] = (seqno >> 8) & 0xff;
    ((uint8_t*)(seqbuf))[15] = seqno & 0xff;

    if (EVP_DecryptInit_ex(ctx_pktlen_,
                           nullptr,
                           nullptr,
                           nullptr,
                           seqbuf) != 1) {
      r = kErrOpenSSL;
      goto out;
    }
    if (EVP_DecryptUpdate(ctx_pktlen_,
                          dec_length_bytes,
                          &outlen,
                          data,
                          data_len) != 1) {
      r = kErrOpenSSL;
      goto out;
    }
    if (static_cast<size_t>(outlen) != 4) {
      r = kErrPartialDecrypt;
      goto out;
    }

    *packet_length = (uint32_t)dec_length_bytes[0] << 24
                     | (uint32_t)dec_length_bytes[1] << 16
                     | (uint32_t)dec_length_bytes[2] << 8
                     | (uint32_t)dec_length_bytes[3];
    memcpy(length_bytes, data, data_len);
out:
    return r;
  }
  ErrorType decrypt_length(unsigned char* data,
                           size_t data_len,
                           uint32_t seqno,
                           uint32_t* packet_length) {
    ErrorType r = kErrNone;
    int outlen;

    unsigned char dec_length_bytes[4];

    uint8_t seqbuf[16] = {0};
    ((uint8_t*)(seqbuf))[12] = (seqno >> 24) & 0xff;
    ((uint8_t*)(seqbuf))[13] = (seqno >> 16) & 0xff;
    ((uint8_t*)(seqbuf))[14] = (seqno >> 8) & 0xff;
    ((uint8_t*)(seqbuf))[15] = seqno & 0xff;

    if (EVP_DecryptInit_ex(ctx_pktlen_,
                           nullptr,
                           nullptr,
                           nullptr,
                           seqbuf) != 1) {
      r = kErrOpenSSL;
      goto out;
    }
    if (EVP_DecryptUpdate(ctx_pktlen_,
                          dec_length_bytes,
                          &outlen,
                          data,
                          data_len) != 1) {
      r = kErrOpenSSL;
      goto out;
    }
    if (static_cast<size_t>(outlen) != 4) {
      r = kErrPartialDecrypt;
      goto out;
    }

    *packet_length = (uint32_t)dec_length_bytes[0] << 24
                     | (uint32_t)dec_length_bytes[1] << 16
                     | (uint32_t)dec_length_bytes[2] << 8
                     | (uint32_t)dec_length_bytes[3];
    memcpy(length_bytes, data, data_len);
out:
    return r;
  }