
Biblioteca para SRTP (Protocolo seguro de transporte en tiempo real)
Este paquete proporciona una implementación del Protocolo de transporte seguro en tiempo real (SRTP), la Transformada de Seguridad Universal (UST) y un núcleo criptográfico de soporte. La API de SRTP está documentada en include/srtp.h, y la biblioteca está en libsrtp2.a (después de la compilación).
Este documento describe libSRTP, la biblioteca Open Source de RTP Seguro de Cisco Systems, Inc. RTP es el Protocolo de transporte en tiempo real, un estándar IETF para el transporte de datos en tiempo real como telefonía, audio y vídeo, definido por RFC 3550. RTP Seguro (SRTP) es un perfil de RTP que proporciona confidencialidad a los datos RTP y autenticación a la cabecera y la carga útil de RTP. SRTP es un estándar IETF, definido en RFC 3711, y fue desarrollado en el Grupo de Trabajo de Transporte de Audio/Vídeo (AVT) de la IETF. Esta biblioteca soporta todas las características obligatorias de SRTP, pero no todas las opcionales. Consulte la sección Características compatibles para obtener información más detallada.
Este documento también se utiliza para generar los archivos de documentación en la carpeta /doc/, donde se puede crear una referencia más detallada de la API de libSRTP y de las funciones relacionadas (requiere instalar doxygen). El material de referencia se crea automáticamente a partir de los comentarios incrustados en algunos de los archivos de cabecera de C. La documentación está organizada en módulos para mejorar su claridad. Estos módulos no se corresponden directamente con los archivos. Un núcleo criptográfico subyacente proporciona gran parte de la funcionalidad básica de libSRTP, pero está mayormente sin documentar porque realiza su trabajo entre bastidores.
[email protected] lista general de correo para noticias / anuncios / debates. Esta es una lista abierta; consulte https://lists.packetizer.com/mailman/listinfo/libsrtp para suscribirse.
[email protected] para divulgar problemas de seguridad al equipo de mantenimiento de libsrtp. Esta es una lista cerrada, pero cualquiera puede enviar mensajes a ella.
libSRTP se distribuye bajo la siguiente licencia, que se incluye en la distribución del código fuente. Se reproduce en el manual por si ha obtenido la biblioteca de otra fuente.
Derechos de autor (c) 2001-2017 Cisco Systems, Inc. Todos los derechos reservados.
Se permite la redistribución y el uso en forma de código fuente y binaria, con o sin modificaciones, siempre que se cumplan las siguientes condiciones:
- Las redistribuciones del código fuente deben conservar el aviso de derechos de autor anterior, esta lista de condiciones y el siguiente descargo de responsabilidad.
- Las redistribuciones en forma binaria deben reproducir el aviso de derechos de autor anterior, esta lista de condiciones y el siguiente descargo de responsabilidad en la documentación y/u otros materiales proporcionados con la distribución.
- Ni el nombre de Cisco Systems, Inc. ni los nombres de sus contribuyentes podrán utilizarse para respaldar o promocionar productos derivados de este software sin un permiso previo por escrito.
ESTE SOFTWARE SE PROPORCIONA POR LOS TITULARES DE LOS DERECHOS DE AUTOR Y LOS CONTRIBUYENTES "TAL CUAL" Y SE RECHAZA CUALQUIER GARANTÍA EXPRESA O IMPLÍCITA, INCLUIDAS, ENTRE OTRAS, LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UN FIN PARTICULAR. EN NINGÚN CASO LOS TITULARES DE LOS DERECHOS DE AUTOR O LOS CONTRIBUYENTES SERÁN RESPONSABLES DE NINGÚN DAÑO DIRECTO, INDIRECTO, INCIDENTAL, ESPECIAL, EJEMPLAR O CONSECUENTE (INCLUIDOS, ENTRE OTROS, LA ADQUISICIÓN DE BIENES O SERVICIOS SUSTITUTOS; LA PÉRDIDA DE USO, DATOS O BENEFICIOS; O LA INTERRUPCIÓN DEL NEGOCIO), CUALQUIERA QUE SEA SU CAUSA Y BAJO CUALQUIER TEORÍA DE RESPONSABILIDAD, YA SEA CONTRACTUAL, RESPONSABILIDAD ESTRICTA O AGRAVIO (INCLUIDA LA NEGLIGENCIA U OTRO TIPO), QUE SURJA DE CUALQUIER MANERA DEL USO DE ESTE SOFTWARE, INCLUSO SI SE HA ADVERTIDO DE LA POSIBILIDAD DE TALES DAÑOS.
libSRTP proporciona funciones para proteger RTP y RTCP. Los paquetes RTP pueden cifrarse y autenticarse (mediante la función srtp_protect()), convirtiéndolos en paquetes SRTP. De manera similar, los paquetes SRTP pueden descifrarse y verificar su autenticación (mediante la función srtp_unprotect()), convirtiéndolos en paquetes RTP. Funciones similares aplican seguridad a los paquetes RTCP.
La definición de tipo srtp_stream_t apunta a una estructura que contiene todo el estado asociado a un flujo SRTP, incluidas las claves y los parámetros de las funciones de cifrado y autenticación de mensajes, así como los datos antirrepetición. Un srtp_stream_t concreto contiene la información necesaria para proteger un flujo RTP y RTCP específico. Este tipo de datos es deliberadamente opaco para separar mejor la API de libSRTP de su implementación.
Dentro de una sesión SRTP puede haber múltiples flujos, cada uno originado por un remitente concreto. Cada fuente utiliza un contexto de flujo distinto para proteger el flujo RTP y RTCP que origina. La definición de tipo srtp_t apunta a una estructura que contiene todo el estado asociado a una sesión SRTP. Puede haber múltiples contextos de flujo asociados a un único srtp_t. Un contexto de flujo no puede existir de forma independiente a un srtp_t, aunque, por supuesto, se puede crear un srtp_t que contenga un único contexto de flujo. Un dispositivo que participa en una sesión SRTP debe tener un contexto de flujo para cada fuente de esa sesión, de modo que pueda procesar los datos que recibe de cada remitente.
En libSRTP, una sesión se crea mediante la función srtp_create(). La política que se implementará en la sesión se pasa a esta función como un manejador opaco srtp_policy_t. Un único manejador de política describe una política de flujo. Para configurar múltiples flujos, cree una sesión y añada políticas adicionales con srtp_stream_add().
Un manejador de política se configura con las funciones srtp_policy_set_*. Como mínimo, esto incluye la selección de SSRC, la selección de perfil y el material de clave/sal. El perfil configura los ajustes de política criptográfica RTP/RTCP, mientras que el selector de SSRC identifica cómo y dónde se aplica esa política.
En esta sección revisamos SRTP e introducimos algunos términos que se utilizan en libSRTP. Una sesión RTP se define por un par de direcciones de transporte de destino, es decir, una dirección de red más un par de puertos UDP para RTP y RTCP. RTCP, el protocolo de control de RTP, se utiliza para coordinar a los participantes de una sesión RTP, por ejemplo, para proporcionar retroalimentación de los receptores a los remitentes. Una sesión SRTP se define de manera similar; es simplemente una sesión RTP en la que se utiliza el perfil SRTP. Una sesión SRTP consiste en el tráfico enviado a las direcciones de transporte de destino SRTP o SRTCP. Cada participante en una sesión se identifica mediante un identificador de fuente de sincronización (SSRC). Algunos participantes pueden no enviar tráfico SRTP; se les denomina receptores, aunque envíen tráfico SRTCP, como los informes de receptor.
RTP permite que múltiples fuentes envíen tráfico RTP y RTCP durante la misma sesión. El identificador de fuente de sincronización (SSRC) se utiliza para distinguir estas fuentes. En libSRTP, llamamos flujo al tráfico SRTP y SRTCP de una fuente concreta. Cada flujo tiene su propio SSRC, número de secuencia, contador de reinicio y otros datos. Una elección concreta de opciones, mecanismos criptográficos y claves se denomina política. Cada flujo dentro de una sesión puede tener una política distinta aplicada.
Una única política puede utilizarse para todos los flujos de una sesión determinada, aunque el caso en el que una única clave se comparte entre múltiples flujos requiere cuidado. Cuando se utiliza el uso compartido de claves, los valores SSRC que identifican los flujos deben ser distintos. Este requisito puede aplicarse mediante la convención de que cada clave SRTP y SRTCP sea utilizada para el cifrado por un único remitente. En otras palabras, la clave se comparte solo entre flujos que se originan en un dispositivo concreto (por supuesto, otros participantes SRTP necesitarán usar la clave para el descifrado). libSRTP admite esta aplicación detectando el caso en el que una clave se usa para datos entrantes y salientes.
Esta biblioteca soporta todas las características de implementación obligatoria de SRTP (según se define en RFC 3711). Algunas de estas características pueden seleccionarse (o deseleccionarse) en tiempo de ejecución estableciendo una política adecuada mediante un manejador srtp_policy_t. Algunos otros comportamientos del protocolo pueden adaptarse definiendo un manejador de eventos apropiado para los eventos excepcionales; consulte la sección SRTPevents en la documentación generada.
Algunas opciones descritas en la especificación SRTP no son compatibles. Esto incluye
El usuario debe ser consciente de que es posible hacer un uso indebido de esta biblioteca y de que el resultado puede ser que el nivel de seguridad que proporciona sea inadecuado. Si está implementando una funcionalidad con esta biblioteca, querrá leer la sección Security Considerations de RFC 3711. Además, es importante que lea y comprenda los términos descritos en la sección Licencia y descargo de responsabilidad.
Esta biblioteca también soporta los métodos de cifrado autenticado AES-GCM descritos en RFC 7714
Es posible configurar con qué backend criptográfico de terceros (p. ej., openssl/nss/etc.) se compilará libSRTP. Si no se establece ningún backend de terceros, libSRTP proporciona una implementación interna de AES y Sha1. La implementación interna solo soporta AES-128 y AES-256, por lo que para usar AES-192 o el grupo de cifradores AES-GCM debe configurarse un backend criptográfico de terceros. Por esta razón y por motivos de rendimiento, se recomienda encarecidamente utilizar un backend criptográfico de terceros.
La función srtp_protect() asume que el búfer que contiene el paquete rtp tiene suficiente almacenamiento asignado para que la etiqueta de autenticación pueda escribirse al final de ese paquete. Si esta suposición no es válida, se producirá corrupción de memoria.
Se proporcionan pruebas automatizadas para las funciones criptográficas mediante las funciones cipher_type_self_test() y auth_type_self_test(). Estas funciones deben utilizarse para probar cada port de este código a una nueva plataforma.
La protección antirrepetición está contenida en el motor criptográfico, y se proporcionan pruebas para ella.
Esta implementación proporciona llamadas para inicializar, proteger y desproteger paquetes RTP, y hace las mínimas suposiciones posibles sobre cómo se llamarán estas funciones. Por ejemplo, no se espera que el llamador proporcione los paquetes en orden (aunque si se llaman más de 65k fuera de secuencia, se perderá la sincronización).
El número de secuencia del paquete rtp se utiliza como los 16 bits menos significativos del índice de paquetes local del remitente. Tenga en cuenta que RTP comenzará su número de secuencia en un lugar aleatorio, y la capa SRTP simplemente salta hacia adelante a ese número en su primera invocación. Una versión anterior de esta biblioteca utilizaba números de secuencia iniciales inferiores a 32,768; este truco ya no es necesario, ya que la función rdbx_estimate_index(...) se ha vuelto más inteligente a partir de la versión 1.0.1.
La ventana antirrepetición para (S)RTCP está fijada a 128 bits de longitud.
Para instalar libSRTP, descargue la última versión de la distribución desde https://github.com/cisco/libsrtp/releases. Probablemente quiera obtener la versión más reciente. Descomprima la distribución y extraiga los archivos fuente; el directorio en el que se colocarán los archivos fuente se llama libsrtp-A-B-C, donde A es el número de versión, B es el número de versión principal y C es el número de versión menor.
libSRTP utiliza las utilidades GNU autoconf y make (BSD make no funcionará; si ambas versiones de make están en su plataforma, puede invocar GNU make como gmake.). En el directorio libsrtp, ejecute el script configure y luego make:~~~.txt
./configure [ options ]
make
El script de configuración acepta las siguientes opciones:
Option | Description
-------------------------------|--------------------
\-\-help \-h | Display help
\-\-enable-debug-logging | Enable debug logging in all modules
\-\-enable-openssl | Enable OpenSSL crypto engine
\-\-enable-nss | Enable NSS crypto engine
\-\-enable-openssl-kdf | Enable OpenSSL KDF algorithm
\-\-enable-log-stdout | Enable logging to stdout
\-\-with-openssl-dir | Location of OpenSSL installation
\-\-with-nss-dir | Location of NSS installation
\-\-with-log-file | Use file for logging
De forma predeterminada no hay salida de registro; el registro puede habilitarse para salir a stdout o a un archivo determinado mediante las opciones de configuración.
Este paquete ha sido probado en las siguientes plataformas: Mac OS X (powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris (sparc-sun-solaris2.6), RedHat Linux 7.1 y 9 (i686-pc-linux), y OpenBSD (sparc-unknown-openbsd2.7).
--------------------------------------------------------------------------------
<a name="changing-build-configuration"></a>
## Cambiar la configuración de compilación
Para generar el script `./configure` mencionado anteriormente, libSRTP depende del conjunto de herramientas [automake](https://www.gnu.org/software/automake/). Dado que `./configure` se genera a partir de `configure.in` mediante automake, si realiza cambios en el funcionamiento de `./configure` (por ejemplo, para agregar una nueva dependencia de biblioteca), necesitará reconstruir `./configure` y confirmar la versión actualizada. Además de automake en sí, también necesitará tener instaladas las herramientas `pkgconfig`.
Por ejemplo, en macOS:```
brew install automake pkgconfig
# Edit configure.in
autoremake -ivf
```
<a name="using-visual-studio"></a>
## Uso de Visual Studio
En Windows se puede usar Visual Studio mediante CMake. CMake se puede descargar aquí:
https://cmake.org/ . Para crear archivos de compilación de Visual Studio, por ejemplo ejecute los
siguientes comandos:```
# Create build subdirectory
mkdir build
cd build
# Make project files
cmake .. -G "Visual Studio 15 2017"
# Or for 64 bit project files
cmake .. -G "Visual Studio 15 2017 Win64"
```
<a name="using-meson"></a>
## Usando Meson
En todas las plataformas, incluyendo Windows, se puede compilar usando [Meson](https://mesonbuild.com).
Los pasos para descargar Meson están aquí: https://mesonbuild.com/Getting-meson.html
Para compilar con Meson, puedes hacer algo como:```
# Setup the build subdirectory
meson setup --prefix=/path/to/prefix builddir
# Build the project
meson compile -C builddir
# Run tests
meson test -C builddir
# Optionally, install
meson install -C builddir
```
Para compilar con Visual Studio, ejecute los comandos anteriores desde un símbolo
del sistema de Visual Studio, o ejecute `vcvarsall.bat` con los argumentos apropiados
dentro de un Símbolo del sistema.
Tenga en cuenta que también puede reemplazar los comandos anteriores con los objetivos
`ninja` apropiados: `ninja -C build`, `ninja -C build test`, `ninja -C build install`.
--------------------------------------------------------------------------------
<a name="applications"></a>
# Aplicaciones
Varios controladores de prueba y una aplicación srtp simple y portátil se
incluyen en el subdirectorio `test/`.
Controlador de prueba | Función probada
--------- | -------
kernel_driver | núcleo criptográfico (cifrados, funciones de autenticación, rng)
srtp_driver | pruebas de srtp en memoria (no usa la red)
rdbx_driver | rdbx (base de datos de reproducción extendida)
roc_driver | funciones extendidas de número de secuencia
replay_driver | base de datos de reproducción
cipher_driver | cifrados
auth_driver | funciones hash
La aplicación `rtpw` es una aplicación rtp simple que lee palabras de
`/usr/dict/words` y las envía una a la vez usando [s]rtp.
El establecimiento manual de claves srtp usa la opción -k; la gestión automatizada
de claves mediante gdoi se añadirá más adelante.
uso:~~~.txt
rtpw [[-d <debug>]* [-k|b <key> [-a][-e <key size>][-g]] [-s | -r] dest_ip dest_port] | [-l]
Debe elegirse la opción -s (emisor) o la opción -r (receptor). Los valores dest_ip, dest_port son la dirección IP y el puerto UDP a los que se enviará el diccionario, respectivamente.
Las opciones son:
Para obtener valores aleatorios de 30 bytes para usar como pares clave/sal, puede usar la siguiente función bash para formatear la salida de /dev/random (donde ese dispositivo esté disponible).~~~.txt
function randhex() {
cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }'
}
A continuación se muestra un ejemplo de una sesión SRTP que utiliza dos programas rtpw:~~~.txt
set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
[sh1]$ test/rtpw -s -k $k -e 128 -a 0.0.0.0 9999
Security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
setting SSRC to 2078917053
sending word: A
sending word: a
sending word: aa
sending word: aal
...
[sh2]$ test/rtpw -r -k $k -e 128 -a 0.0.0.0 9999
security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
19 octets received from SSRC 2078917053 word: A
19 octets received from SSRC 2078917053 word: a
20 octets received from SSRC 2078917053 word: aa
21 octets received from SSRC 2078917053 word: aal
...
Esta sección proporciona un ejemplo sencillo de cómo usar libSRTP. Aquí asumimos
que las funciones get_rtp_packet() y send_srtp_packet() están disponibles
para nosotros. La primera coloca un paquete RTP
en el búfer y devuelve el número de octetos escritos en ese
búfer. La segunda envía el paquete RTP en el búfer, dada la
longitud como su segundo argumento.~~~.c
srtp_t session;
srtp_policy_t policy;
// Set key/salt to predetermined values. uint8_t master_key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; uint8_t master_salt[14] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D};
// Initialize libSRTP. srtp_init();
// Create and configure an opaque policy handle. srtp_policy_create(&policy); srtp_policy_set_ssrc(policy, (srtp_ssrc_t){ssrc_any_outbound, 0}); srtp_policy_set_profile(policy, srtp_profile_aes128_cm_sha1_80); srtp_policy_add_key(policy, master_key, sizeof(master_key), master_salt, sizeof(master_salt), NULL, 0);
// Allocate and initialize the SRTP session. srtp_create(&session, policy);
srtp_policy_destroy(policy);
// Main loop: get RTP packets, send SRTP packets. while (1) { char rtp_buffer[2048]; size_t rtp_len; char srtp_buffer[2048]; size_t srtp_len = sizeof(srtp_buffer);
rtp_len = get_rtp_packet(rtp_buffer); srtp_protect(session, rtp_buffer, rtp_len, srtp_buffer, &srtp_len); send_srtp_packet(srtp_buffer, srtp_len); }
srtp_dealloc(session); srtp_shutdown();
<a name="credits"></a>
# Créditos
La implementación original y la documentación de libSRTP fueron escritas
por David McGrew de Cisco Systems, Inc. con el fin de promover el uso,
la comprensión y la interoperabilidad de Secure RTP. Michael Jerris
contribuyó con soporte para compilar con MSVC. Andris Pavenis
contribuyó con muchas correcciones importantes. Brian West contribuyó con cambios para
habilitar el enlace dinámico. Yves Shumann informó errores de documentación.
Randell Jesup contribuyó con una implementación funcional de SRTCP y otras
correcciones. Steve Underwood contribuyó con cambios de portabilidad para x86_64. También agradecemos
a Fredrik Thulin, Brian Weis, Mark Baugher, Jeff Chan, Bill
Simon, Douglas Smith, Bill May, Richard Preistley, Joe Tardo y
otros por sus contribuciones, comentarios y correcciones.
Este material de referencia, cuando corresponde, en esta documentación se generó
mediante la utilidad doxygen para la documentación automática de código fuente.
Copyright 2001-2005 de David A. McGrew, Cisco Systems, Inc.
--------------------------------------------------------------------------------
<a name="references"></a>
# Referencias
Referencias de SRTP e ICM
Septiembre de 2005
Secure RTP está definido en [RFC 3711](https://tools.ietf.org/html/rfc3711).
La definición del modo contador está en la [Sección 4.1.1](https://tools.ietf.org/html/rfc3711#section-4.1.1).
SHA-1 está definido en [FIPS PUB 180-4](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
HMAC está definido en [RFC 2104](https://tools.ietf.org/html/rfc2104)
y los vectores de prueba HMAC-SHA1 están disponibles
en [RFC 2202](https://tools.ietf.org/html/rfc2202#section-3).
El uso de AES-GCM en SRTP está definido en [RFC 7714](https://tools.ietf.org/html/rfc7714)
| Option | Description |
|---|
| -s | (S)RTP emisor - hace que la aplicación envíe palabras |
| -r | (S)RTP receptor - hace que la aplicación reciba palabras |
| -k | usa la clave maestra SRTP , donde la clave es un hexadecimal (sin el prefijo "0x") |
| -b | igual que -k pero con la clave codificada en base64 |
| -e | cifrar/descifrar (para confidencialidad de datos) (requiere también el uso de la opción -k) (use 128, 192 o 256 para el tamaño de clave) |
| -g | usa el modo AES-GCM (debe usarse con -e) |
| -a | autenticación de mensajes (requiere también el uso de la opción -k) |
| -l | lista los módulos de depuración disponibles |
| -d | activa la depuración para el módulo |